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;
153 EggLoader(
const EggData *data) :
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:
903 case EggTexture::F_srgb:
905 wanted_alpha =
false;
908 case EggTexture::F_rgba:
909 case EggTexture::F_rgbm:
910 case EggTexture::F_rgba12:
911 case EggTexture::F_rgba8:
912 case EggTexture::F_rgba4:
913 case EggTexture::F_rgba5:
914 case EggTexture::F_srgb_alpha:
919 case EggTexture::F_unspecified:
926 if (_record !=
nullptr) {
935 if (egg_preload_simple_textures) {
936 options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_preload_simple);
939 if (!egg_ignore_filters && !egg_ignore_mipmaps) {
940 switch (egg_tex->get_minfilter()) {
941 case EggTexture::FT_nearest:
942 case EggTexture::FT_linear:
943 case EggTexture::FT_unspecified:
946 case EggTexture::FT_nearest_mipmap_nearest:
947 case EggTexture::FT_linear_mipmap_nearest:
948 case EggTexture::FT_nearest_mipmap_linear:
949 case EggTexture::FT_linear_mipmap_linear:
950 options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_generate_mipmaps);
955 options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_multiview);
962 if (egg_tex->get_compression_mode() == EggTexture::CM_on) {
963 options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_allow_compression);
967 switch (egg_tex->get_texture_type()) {
968 case EggTexture::TT_unspecified:
969 case EggTexture::TT_1d_texture:
970 options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_allow_1d);
973 case EggTexture::TT_2d_texture:
987 case EggTexture::TT_3d_texture:
992 case EggTexture::TT_cube_map:
998 if (tex ==
nullptr) {
1013 if (aux !=
nullptr &&
1014 aux->
is_of_type(EggTexture::get_class_type())) {
1017 if (aux_egg_tex->
get_alpha_mode() != EggTexture::AM_unspecified) {
1020 if (aux_egg_tex->get_format() != EggTexture::F_unspecified) {
1021 egg_tex->set_format(aux_egg_tex->get_format());
1023 if (aux_egg_tex->get_minfilter() != EggTexture::FT_unspecified) {
1024 egg_tex->set_minfilter(aux_egg_tex->get_minfilter());
1026 if (aux_egg_tex->get_magfilter() != EggTexture::FT_unspecified) {
1027 egg_tex->set_magfilter(aux_egg_tex->get_magfilter());
1034 apply_texture_attributes(tex, egg_tex);
1038 def._texture = DCAST(
TextureAttrib, TextureAttrib::make())->add_on_stage(stage, tex);
1040 def._egg_tex = egg_tex;
1051 if (egg_tex->get_compression_mode() != EggTexture::CM_default) {
1052 tex->
set_compression(convert_compression_mode(egg_tex->get_compression_mode()));
1061 if (wrap_u != EggTexture::WM_unspecified) {
1062 sampler.
set_wrap_u(convert_wrap_mode(wrap_u));
1064 if (wrap_v != EggTexture::WM_unspecified) {
1065 sampler.
set_wrap_v(convert_wrap_mode(wrap_v));
1067 if (wrap_w != EggTexture::WM_unspecified) {
1068 sampler.
set_wrap_w(convert_wrap_mode(wrap_w));
1075 switch (egg_tex->get_minfilter()) {
1076 case EggTexture::FT_nearest:
1080 case EggTexture::FT_linear:
1081 if (egg_ignore_filters) {
1082 egg2pg_cat.warning()
1083 <<
"Ignoring minfilter request\n";
1090 case EggTexture::FT_nearest_mipmap_nearest:
1091 if (egg_ignore_filters) {
1092 egg2pg_cat.warning()
1093 <<
"Ignoring minfilter request\n";
1095 }
else if (egg_ignore_mipmaps) {
1096 egg2pg_cat.warning()
1097 <<
"Ignoring mipmap request\n";
1100 sampler.
set_minfilter(SamplerState::FT_nearest_mipmap_nearest);
1104 case EggTexture::FT_linear_mipmap_nearest:
1105 if (egg_ignore_filters) {
1106 egg2pg_cat.warning()
1107 <<
"Ignoring minfilter request\n";
1109 }
else if (egg_ignore_mipmaps) {
1110 egg2pg_cat.warning()
1111 <<
"Ignoring mipmap request\n";
1114 sampler.
set_minfilter(SamplerState::FT_linear_mipmap_nearest);
1118 case EggTexture::FT_nearest_mipmap_linear:
1119 if (egg_ignore_filters) {
1120 egg2pg_cat.warning()
1121 <<
"Ignoring minfilter request\n";
1123 }
else if (egg_ignore_mipmaps) {
1124 egg2pg_cat.warning()
1125 <<
"Ignoring mipmap request\n";
1128 sampler.
set_minfilter(SamplerState::FT_nearest_mipmap_linear);
1132 case EggTexture::FT_linear_mipmap_linear:
1133 if (egg_ignore_filters) {
1134 egg2pg_cat.warning()
1135 <<
"Ignoring minfilter request\n";
1137 }
else if (egg_ignore_mipmaps) {
1138 egg2pg_cat.warning()
1139 <<
"Ignoring mipmap request\n";
1142 sampler.
set_minfilter(SamplerState::FT_linear_mipmap_linear);
1146 case EggTexture::FT_unspecified:
1150 switch (egg_tex->get_magfilter()) {
1151 case EggTexture::FT_nearest:
1152 case EggTexture::FT_nearest_mipmap_nearest:
1153 case EggTexture::FT_nearest_mipmap_linear:
1157 case EggTexture::FT_linear:
1158 case EggTexture::FT_linear_mipmap_nearest:
1159 case EggTexture::FT_linear_mipmap_linear:
1160 if (egg_ignore_filters) {
1161 egg2pg_cat.warning()
1162 <<
"Ignoring magfilter request\n";
1169 case EggTexture::FT_unspecified:
1191 bool force_srgb =
false;
1192 if (egg_force_srgb_textures) {
1193 switch (egg_tex->get_env_type()) {
1194 case EggTexture::ET_unspecified:
1195 case EggTexture::ET_modulate:
1196 case EggTexture::ET_decal:
1197 case EggTexture::ET_blend:
1198 case EggTexture::ET_replace:
1199 case EggTexture::ET_add:
1200 case EggTexture::ET_blend_color_scale:
1201 case EggTexture::ET_modulate_glow:
1202 case EggTexture::ET_modulate_gloss:
1204 if (egg2pg_cat.is_debug()) {
1206 <<
"Enabling sRGB format on texture " << egg_tex->get_name() <<
"\n";
1216 switch (egg_tex->get_format()) {
1217 case EggTexture::F_red:
1220 case EggTexture::F_green:
1223 case EggTexture::F_blue:
1226 case EggTexture::F_alpha:
1229 case EggTexture::F_luminance:
1230 tex->
set_format(force_srgb ? Texture::F_sluminance : Texture::F_luminance);
1234 egg2pg_cat.warning()
1235 <<
"Ignoring inappropriate format " << egg_tex->get_format()
1236 <<
" for 1-component texture " << egg_tex->get_name() <<
"\n";
1238 case EggTexture::F_unspecified:
1246 switch (egg_tex->get_format()) {
1247 case EggTexture::F_luminance_alpha:
1248 tex->
set_format(force_srgb ? Texture::F_sluminance_alpha : Texture::F_luminance_alpha);
1251 case EggTexture::F_luminance_alphamask:
1252 tex->
set_format(force_srgb ? Texture::F_sluminance_alpha : Texture::F_luminance_alphamask);
1256 egg2pg_cat.warning()
1257 <<
"Ignoring inappropriate format " << egg_tex->get_format()
1258 <<
" for 2-component texture " << egg_tex->get_name() <<
"\n";
1260 case EggTexture::F_unspecified:
1262 tex->
set_format(Texture::F_sluminance_alpha);
1268 switch (egg_tex->get_format()) {
1269 case EggTexture::F_rgb:
1270 tex->
set_format(force_srgb ? Texture::F_srgb : Texture::F_rgb);
1272 case EggTexture::F_rgb12:
1279 egg2pg_cat.warning()
1280 <<
"Ignoring inappropriate format " << egg_tex->get_format()
1281 <<
" for 8-bit texture " << egg_tex->get_name() <<
"\n";
1284 case EggTexture::F_rgb8:
1285 case EggTexture::F_rgba8:
1288 tex->
set_format(force_srgb ? Texture::F_srgb : Texture::F_rgb8);
1290 case EggTexture::F_rgb5:
1291 tex->
set_format(force_srgb ? Texture::F_srgb : Texture::F_rgb5);
1293 case EggTexture::F_rgb332:
1294 tex->
set_format(force_srgb ? Texture::F_srgb : Texture::F_rgb332);
1296 case EggTexture::F_srgb:
1297 case EggTexture::F_srgb_alpha:
1302 egg2pg_cat.warning()
1303 <<
"Ignoring inappropriate format " << egg_tex->get_format()
1304 <<
" for 3-component texture " << egg_tex->get_name() <<
"\n";
1306 case EggTexture::F_unspecified:
1314 switch (egg_tex->get_format()) {
1315 case EggTexture::F_rgba:
1316 tex->
set_format(force_srgb ? Texture::F_srgb_alpha : Texture::F_rgba);
1318 case EggTexture::F_rgbm:
1319 tex->
set_format(force_srgb ? Texture::F_srgb_alpha : Texture::F_rgbm);
1321 case EggTexture::F_rgba12:
1326 tex->
set_format(force_srgb ? Texture::F_srgb_alpha : Texture::F_rgba12);
1328 egg2pg_cat.warning()
1329 <<
"Ignoring inappropriate format " << egg_tex->get_format()
1330 <<
" for 8-bit texture " << egg_tex->get_name() <<
"\n";
1333 case EggTexture::F_rgba8:
1334 tex->
set_format(force_srgb ? Texture::F_srgb_alpha : Texture::F_rgba8);
1336 case EggTexture::F_rgba4:
1337 tex->
set_format(force_srgb ? Texture::F_srgb_alpha : Texture::F_rgba4);
1339 case EggTexture::F_rgba5:
1340 tex->
set_format(force_srgb ? Texture::F_srgb_alpha : Texture::F_rgba5);
1342 case EggTexture::F_srgb_alpha:
1347 egg2pg_cat.warning()
1348 <<
"Ignoring inappropriate format " << egg_tex->get_format()
1349 <<
" for 4-component texture " << egg_tex->get_name() <<
"\n";
1351 case EggTexture::F_unspecified:
1359 if (force_srgb && tex->
get_format() != Texture::F_alpha &&
1361 egg2pg_cat.warning()
1362 <<
"Unable to enable sRGB format on texture " << egg_tex->get_name()
1363 <<
" with specified format " << egg_tex->get_format() <<
"\n";
1366 switch (egg_tex->get_quality_level()) {
1367 case EggTexture::QL_unspecified:
1368 case EggTexture::QL_default:
1372 case EggTexture::QL_fastest:
1376 case EggTexture::QL_normal:
1380 case EggTexture::QL_best:
1391 Texture::CompressionMode EggLoader::
1392 convert_compression_mode(EggTexture::CompressionMode compression_mode)
const {
1393 switch (compression_mode) {
1394 case EggTexture::CM_off:
1395 return Texture::CM_off;
1397 case EggTexture::CM_on:
1398 return Texture::CM_on;
1400 case EggTexture::CM_fxt1:
1401 return Texture::CM_fxt1;
1403 case EggTexture::CM_dxt1:
1404 return Texture::CM_dxt1;
1406 case EggTexture::CM_dxt2:
1407 return Texture::CM_dxt2;
1409 case EggTexture::CM_dxt3:
1410 return Texture::CM_dxt3;
1412 case EggTexture::CM_dxt4:
1413 return Texture::CM_dxt4;
1415 case EggTexture::CM_dxt5:
1416 return Texture::CM_dxt5;
1418 case EggTexture::CM_default:
1419 return Texture::CM_default;
1422 egg2pg_cat.warning()
1423 <<
"Unexpected texture compression flag: " << (int)compression_mode <<
"\n";
1424 return Texture::CM_default;
1431 SamplerState::WrapMode EggLoader::
1432 convert_wrap_mode(EggTexture::WrapMode wrap_mode)
const {
1433 switch (wrap_mode) {
1434 case EggTexture::WM_clamp:
1435 return SamplerState::WM_clamp;
1437 case EggTexture::WM_repeat:
1438 return SamplerState::WM_repeat;
1440 case EggTexture::WM_mirror:
1441 return SamplerState::WM_mirror;
1443 case EggTexture::WM_mirror_once:
1444 return SamplerState::WM_mirror_once;
1446 case EggTexture::WM_border_color:
1447 return SamplerState::WM_border_color;
1449 case EggTexture::WM_unspecified:
1450 return SamplerState::WM_repeat;
1453 egg2pg_cat.warning()
1454 <<
"Unexpected texture wrap flag: " << (int)wrap_mode <<
"\n";
1455 return SamplerState::WM_repeat;
1462 make_texture_stage(
const EggTexture *egg_tex) {
1469 (egg_tex->get_env_type() == EggTexture::ET_unspecified ||
1470 egg_tex->get_env_type() == EggTexture::ET_modulate) &&
1471 egg_tex->get_combine_mode(EggTexture::CC_rgb) == EggTexture::CM_unspecified &&
1472 egg_tex->get_combine_mode(EggTexture::CC_alpha) == EggTexture::CM_unspecified &&
1482 switch (egg_tex->get_env_type()) {
1483 case EggTexture::ET_modulate:
1484 stage->set_mode(TextureStage::M_modulate);
1487 case EggTexture::ET_decal:
1488 stage->set_mode(TextureStage::M_decal);
1491 case EggTexture::ET_blend:
1492 stage->set_mode(TextureStage::M_blend);
1495 case EggTexture::ET_replace:
1496 stage->set_mode(TextureStage::M_replace);
1499 case EggTexture::ET_add:
1500 stage->set_mode(TextureStage::M_add);
1503 case EggTexture::ET_blend_color_scale:
1504 stage->set_mode(TextureStage::M_blend_color_scale);
1507 case EggTexture::ET_modulate_glow:
1508 stage->set_mode(TextureStage::M_modulate_glow);
1511 case EggTexture::ET_modulate_gloss:
1512 stage->set_mode(TextureStage::M_modulate_gloss);
1515 case EggTexture::ET_normal:
1516 stage->set_mode(TextureStage::M_normal);
1519 case EggTexture::ET_normal_height:
1520 stage->set_mode(TextureStage::M_normal_height);
1523 case EggTexture::ET_glow:
1524 stage->set_mode(TextureStage::M_glow);
1527 case EggTexture::ET_gloss:
1528 stage->set_mode(TextureStage::M_gloss);
1531 case EggTexture::ET_height:
1532 stage->set_mode(TextureStage::M_height);
1535 case EggTexture::ET_selector:
1536 stage->set_mode(TextureStage::M_selector);
1539 case EggTexture::ET_normal_gloss:
1540 stage->set_mode(TextureStage::M_normal_gloss);
1543 case EggTexture::ET_unspecified:
1547 switch (egg_tex->get_combine_mode(EggTexture::CC_rgb)) {
1548 case EggTexture::CM_replace:
1549 stage->set_combine_rgb(get_combine_mode(egg_tex, EggTexture::CC_rgb),
1550 get_combine_source(egg_tex, EggTexture::CC_rgb, 0),
1551 get_combine_operand(egg_tex, EggTexture::CC_rgb, 0));
1554 case EggTexture::CM_modulate:
1555 case EggTexture::CM_add:
1556 case EggTexture::CM_add_signed:
1557 case EggTexture::CM_subtract:
1558 case EggTexture::CM_dot3_rgb:
1559 case EggTexture::CM_dot3_rgba:
1560 stage->set_combine_rgb(get_combine_mode(egg_tex, EggTexture::CC_rgb),
1561 get_combine_source(egg_tex, EggTexture::CC_rgb, 0),
1562 get_combine_operand(egg_tex, EggTexture::CC_rgb, 0),
1563 get_combine_source(egg_tex, EggTexture::CC_rgb, 1),
1564 get_combine_operand(egg_tex, EggTexture::CC_rgb, 1));
1567 case EggTexture::CM_interpolate:
1568 stage->set_combine_rgb(get_combine_mode(egg_tex, EggTexture::CC_rgb),
1569 get_combine_source(egg_tex, EggTexture::CC_rgb, 0),
1570 get_combine_operand(egg_tex, EggTexture::CC_rgb, 0),
1571 get_combine_source(egg_tex, EggTexture::CC_rgb, 1),
1572 get_combine_operand(egg_tex, EggTexture::CC_rgb, 1),
1573 get_combine_source(egg_tex, EggTexture::CC_rgb, 2),
1574 get_combine_operand(egg_tex, EggTexture::CC_rgb, 2));
1577 case EggTexture::CM_unspecified:
1581 switch (egg_tex->get_combine_mode(EggTexture::CC_alpha)) {
1582 case EggTexture::CM_replace:
1583 stage->set_combine_alpha(get_combine_mode(egg_tex, EggTexture::CC_alpha),
1584 get_combine_source(egg_tex, EggTexture::CC_alpha, 0),
1585 get_combine_operand(egg_tex, EggTexture::CC_alpha, 0));
1588 case EggTexture::CM_modulate:
1589 case EggTexture::CM_add:
1590 case EggTexture::CM_add_signed:
1591 case EggTexture::CM_subtract:
1592 stage->set_combine_alpha(get_combine_mode(egg_tex, EggTexture::CC_alpha),
1593 get_combine_source(egg_tex, EggTexture::CC_alpha, 0),
1594 get_combine_operand(egg_tex, EggTexture::CC_alpha, 0),
1595 get_combine_source(egg_tex, EggTexture::CC_alpha, 1),
1596 get_combine_operand(egg_tex, EggTexture::CC_alpha, 1));
1599 case EggTexture::CM_interpolate:
1600 stage->set_combine_alpha(get_combine_mode(egg_tex, EggTexture::CC_alpha),
1601 get_combine_source(egg_tex, EggTexture::CC_alpha, 0),
1602 get_combine_operand(egg_tex, EggTexture::CC_alpha, 0),
1603 get_combine_source(egg_tex, EggTexture::CC_alpha, 1),
1604 get_combine_operand(egg_tex, EggTexture::CC_alpha, 1),
1605 get_combine_source(egg_tex, EggTexture::CC_alpha, 2),
1606 get_combine_operand(egg_tex, EggTexture::CC_alpha, 2));
1609 case EggTexture::CM_unspecified:
1610 case EggTexture::CM_dot3_rgb:
1611 case EggTexture::CM_dot3_rgba:
1618 InternalName::get_texcoord_name(egg_tex->
get_uv_name());
1619 stage->set_texcoord_name(name);
1651 separate_switches(
EggNode *egg_node) {
1652 bool parent_has_switch =
false;
1653 if (egg_node->
is_of_type(EggGroup::get_class_type())) {
1655 parent_has_switch = egg_group->get_switch_flag();
1658 if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
1661 EggGroupNode::iterator ci;
1662 ci = egg_group->begin();
1663 while (ci != egg_group->end()) {
1664 EggGroupNode::iterator cnext;
1669 if (parent_has_switch &&
1670 child->is_of_type(EggPrimitive::get_class_type())) {
1673 egg_group->
replace(ci, new_group.p());
1674 new_group->add_child(child);
1677 separate_switches(child);
1690 emulate_bface(
EggNode *egg_node) {
1691 if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
1695 EggGroupNode::iterator ci;
1696 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1698 if (child->is_of_type(EggPolygon::get_class_type())) {
1704 dup_poly->reverse_vertex_ordering();
1705 if (dup_poly->has_normal()) {
1706 dup_poly->set_normal(-dup_poly->get_normal());
1710 EggPolygon::iterator vi;
1711 for (vi = dup_poly->begin(); vi != dup_poly->end(); ++vi) {
1713 if (vertex->has_normal()) {
1715 dup_vertex.set_normal(-dup_vertex.get_normal());
1717 if (new_vertex != vertex) {
1719 dup_poly->replace(vi, new_vertex);
1723 dup_prims->add_child(dup_poly);
1727 emulate_bface(child);
1741 if (egg_node->
is_of_type(EggBin::get_class_type())) {
1742 return make_node(DCAST(
EggBin, egg_node), parent);
1743 }
else if (egg_node->
is_of_type(EggGroup::get_class_type())) {
1744 return make_node(DCAST(
EggGroup, egg_node), parent);
1745 }
else if (egg_node->
is_of_type(EggTable::get_class_type())) {
1746 return make_node(DCAST(
EggTable, egg_node), parent);
1747 }
else if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
1748 return make_node(DCAST(
EggGroupNode, egg_node), parent);
1762 switch (egg_bin->get_bin_number()) {
1763 case EggBinner::BN_polyset:
1764 case EggBinner::BN_patches:
1765 make_polyset(egg_bin, parent,
nullptr, _dynamic_override, _dynamic_override_char_maker);
1768 case EggBinner::BN_lod:
1769 return make_lod(egg_bin, parent);
1771 case EggBinner::BN_nurbs_surface:
1773 nassertr(!egg_bin->empty(),
nullptr);
1776 DCAST_INTO_R(egg_nurbs, child,
nullptr);
1778 make_nurbs_surface(egg_nurbs, parent, mat);
1782 case EggBinner::BN_nurbs_curve:
1784 nassertr(!egg_bin->empty(),
nullptr);
1787 DCAST_INTO_R(egg_nurbs, child,
nullptr);
1789 make_nurbs_curve(egg_nurbs, parent, mat);
1793 case EggBinner::BN_none:
1806 PT(
LODNode) lod_node = LODNode::make_default_lod(egg_bin->get_name());
1810 EggGroup::const_iterator ci;
1811 for (ci = egg_bin->begin(); ci != egg_bin->end(); ++ci) {
1812 LODInstance instance(*ci);
1813 instances.push_back(instance);
1818 sort(instances.begin(), instances.end());
1820 if (!instances.empty()) {
1823 lod_node->set_center(LCAST(PN_stdfloat, instances[0]._d->_center));
1826 for (
size_t i = 0; i < instances.size(); i++) {
1828 const LODInstance &instance = instances[i];
1829 make_node(instance._egg_node, lod_node);
1833 nassertr(lod_node->get_center().almost_equal
1834 (LCAST(PN_stdfloat, instance._d->_center), 0.01),
nullptr);
1837 lod_node->add_switch(instance._d->_switch_in, instance._d->_switch_out);
1840 _groups[egg_bin] = lod_node;
1841 return create_group_arc(egg_bin, parent, lod_node);
1851 if (egg_group->get_dart_type() != EggGroup::DT_none) {
1853 bool structured = (egg_group->get_dart_type() == EggGroup::DT_structured);
1857 node = char_maker.make_node();
1861 _dynamic_override =
true;
1862 _dynamic_override_char_maker = &char_maker;
1863 EggGroup::const_iterator ci;
1864 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1865 make_node(*ci, node);
1867 _dynamic_override_char_maker =
nullptr;
1868 _dynamic_override =
false;
1871 }
else if (egg_group->get_cs_type() != EggGroup::CST_none) {
1877 node->set_transform(TransformState::make_mat(LCAST(PN_stdfloat, egg_group->
get_vertex_to_node())));
1878 make_collision_solids(egg_group, egg_group, (
CollisionNode *)node.p());
1879 node->clear_transform();
1881 if ((egg_group->get_collide_flags() & EggGroup::CF_keep) != 0) {
1886 parent->add_child(combined);
1887 combined->add_child(node);
1890 EggGroup::const_iterator ci;
1891 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1892 make_node(*ci, combined);
1896 node = create_group_arc(egg_group, parent, node);
1899 }
else if (egg_group->get_portal_flag()) {
1906 set_portal_polygon(egg_group, pnode);
1908 egg2pg_cat.warning()
1909 <<
"Portal " << egg_group->get_name() <<
" has no vertices!\n";
1912 }
else if (egg_group->get_occluder_flag()) {
1919 set_occluder_polygon(egg_group, pnode);
1921 egg2pg_cat.warning()
1922 <<
"Occluder " << egg_group->get_name() <<
" has no vertices!\n";
1925 }
else if (egg_group->get_polylight_flag()) {
1933 if (!make_sphere(egg_group, EggGroup::CF_none, center, radius, color)) {
1934 egg2pg_cat.warning()
1935 <<
"Polylight " << egg_group->get_name() <<
" make_sphere failed!\n";
1946 }
else if (egg_group->get_switch_flag()) {
1947 if (egg_group->get_switch_fps() != 0.0) {
1950 ((
SequenceNode *)node.p())->set_frame_rate(egg_group->get_switch_fps());
1951 _sequences.insert(node);
1954 node =
new SwitchNode(egg_group->get_name());
1957 EggGroup::const_iterator ci;
1958 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1959 make_node(*ci, node);
1961 }
else if (egg_group->has_scrolling_uvs()) {
1962 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());
1964 EggGroup::const_iterator ci;
1965 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1966 make_node(*ci, node);
1969 }
else if (egg_group->get_model_flag() || egg_group->
has_dcs_type()) {
1971 node =
new ModelNode(egg_group->get_name());
1972 switch (egg_group->get_dcs_type()) {
1973 case EggGroup::DC_net:
1974 DCAST(
ModelNode, node)->set_preserve_transform(ModelNode::PT_net);
1977 case EggGroup::DC_no_touch:
1978 DCAST(
ModelNode, node)->set_preserve_transform(ModelNode::PT_no_touch);
1981 case EggGroup::DC_local:
1982 case EggGroup::DC_default:
1983 DCAST(
ModelNode, node)->set_preserve_transform(ModelNode::PT_local);
1986 case EggGroup::DC_none:
1987 case EggGroup::DC_unspecified:
1991 EggGroup::const_iterator ci;
1992 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1993 make_node(*ci, node);
2001 bool all_polysets =
false;
2002 bool any_hidden =
false;
2007 check_for_polysets(egg_group, all_polysets, any_hidden);
2010 if (all_polysets && !any_hidden) {
2011 node =
new GeomNode(egg_group->get_name());
2013 node =
new PandaNode(egg_group->get_name());
2016 EggGroup::const_iterator ci;
2017 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2018 make_node(*ci, node);
2022 if (node ==
nullptr) {
2028 for (
int gri = 0; gri < num_group_refs; ++gri) {
2030 Groups::const_iterator gi = _groups.find(group_ref);
2031 if (gi != _groups.end()) {
2033 node->add_child(node_ref);
2037 _groups[egg_group] = node;
2038 return create_group_arc(egg_group, parent, node);
2048 parent->add_child(node);
2058 switch (egg_group->get_billboard_type()) {
2059 case EggGroup::BT_point_camera_relative:
2060 node->
set_effect(BillboardEffect::make_point_eye());
2063 case EggGroup::BT_point_world_relative:
2064 node->
set_effect(BillboardEffect::make_point_world());
2067 case EggGroup::BT_axis:
2068 node->
set_effect(BillboardEffect::make_axis());
2071 case EggGroup::BT_none:
2075 if (egg_group->get_decal_flag()) {
2076 if (egg_ignore_decals) {
2078 <<
"Ignoring decal flag on " << egg_group->get_name() <<
"\n";
2085 _decals.insert(node);
2089 EggGroup::TagData::const_iterator ti;
2091 node->
set_tag((*ti).first, (*ti).second);
2094 if (egg_group->get_blend_mode() != EggGroup::BM_unspecified &&
2095 egg_group->get_blend_mode() != EggGroup::BM_none) {
2097 ColorBlendAttrib::Mode mode = get_color_blend_mode(egg_group->get_blend_mode());
2098 ColorBlendAttrib::Operand a = get_color_blend_operand(egg_group->get_blend_operand_a());
2099 ColorBlendAttrib::Operand b = get_color_blend_operand(egg_group->get_blend_operand_b());
2101 node->
set_attrib(ColorBlendAttrib::make(mode, a, b, color));
2108 if (egg_group->has_collide_mask()) {
2109 def._from_collide_mask = egg_group->get_collide_mask();
2110 def._into_collide_mask = egg_group->get_collide_mask();
2112 DeferredNodeProperty::F_has_from_collide_mask |
2113 DeferredNodeProperty::F_has_into_collide_mask;
2115 if (egg_group->has_from_collide_mask()) {
2116 def._from_collide_mask = egg_group->get_from_collide_mask();
2117 def._flags |= DeferredNodeProperty::F_has_from_collide_mask;
2119 if (egg_group->has_into_collide_mask()) {
2120 def._into_collide_mask = egg_group->get_into_collide_mask();
2121 def._flags |= DeferredNodeProperty::F_has_into_collide_mask;
2124 if (def._flags != 0) {
2125 _deferred_nodes[node] = def;
2136 if (egg_table->get_table_type() != EggTable::TT_bundle) {
2139 return make_node(DCAST(
EggGroupNode, egg_table), parent);
2145 parent->add_child(node);
2157 EggGroupNode::const_iterator ci;
2158 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2159 make_node(*ci, node);
2162 parent->add_child(node);
2171 check_for_polysets(
EggGroup *egg_group,
bool &all_polysets,
bool &any_hidden) {
2172 all_polysets = (!egg_group->empty());
2175 EggGroup::const_iterator ci;
2176 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2177 if ((*ci)->is_of_type(EggBin::get_class_type())) {
2179 if (egg_bin->get_bin_number() == EggBinner::BN_polyset) {
2182 EggGroup::const_iterator bci = egg_bin->begin();
2183 nassertv(bci != egg_bin->end());
2185 DCAST_INTO_V(first_prim, (*bci));
2187 DCAST_INTO_V(render_state, first_prim->
get_user_data(EggRenderState::get_class_type()));
2189 if (render_state->_hidden) {
2193 all_polysets =
false;
2196 }
else if ((*ci)->is_of_type(EggGroup::get_class_type())) {
2200 all_polysets =
false;
2216 bool ignore_color) {
2217 VertexPoolTransform vpt;
2218 vpt._vertex_pool = vertex_pool;
2219 vpt._bake_in_uvs = render_state->_bake_in_uvs;
2220 vpt._transform = transform;
2222 VertexPoolData::iterator di;
2223 di = _vertex_pool_data.find(vpt);
2224 if (di != _vertex_pool_data.end()) {
2225 return (*di).second;
2231 Geom::NT_stdfloat, Geom::C_point);
2234 array_format->add_column
2235 (InternalName::get_normal(), 3,
2236 Geom::NT_stdfloat, Geom::C_normal);
2239 if (!ignore_color) {
2243 array_format->add_column(InternalName::get_color(), 1,
2244 Geom::NT_packed_dabc, Geom::C_color);
2246 array_format->add_column(InternalName::get_color(), 4,
2247 Geom::NT_uint8, Geom::C_color);
2251 vector_string uv_names, uvw_names, tbn_names;
2252 vertex_pool->
get_uv_names(uv_names, uvw_names, tbn_names);
2253 vector_string::const_iterator ni;
2254 for (ni = uv_names.begin(); ni != uv_names.end(); ++ni) {
2255 string name = (*ni);
2257 PT(
InternalName) iname = InternalName::get_texcoord_name(name);
2259 if (find(uvw_names.begin(), uvw_names.end(), name) != uvw_names.end()) {
2261 array_format->add_column
2262 (iname, 3, Geom::NT_stdfloat, Geom::C_texcoord);
2264 array_format->add_column
2265 (iname, 2, Geom::NT_stdfloat, Geom::C_texcoord);
2268 for (ni = tbn_names.begin(); ni != tbn_names.end(); ++ni) {
2269 string name = (*ni);
2271 PT(
InternalName) iname_t = InternalName::get_tangent_name(name);
2272 PT(
InternalName) iname_b = InternalName::get_binormal_name(name);
2274 array_format->add_column
2275 (iname_t, 3, Geom::NT_stdfloat, Geom::C_vector);
2276 array_format->add_column
2277 (iname_b, 3, Geom::NT_stdfloat, Geom::C_vector);
2280 vector_string aux_names;
2282 for (ni = aux_names.begin(); ni != aux_names.end(); ++ni) {
2283 string name = (*ni);
2285 array_format->add_column
2286 (iname, 4, Geom::NT_stdfloat, Geom::C_other);
2292 string name = _data->get_egg_filename().get_basename_wo_extension();
2303 temp_format->set_animation(animation);
2307 (InternalName::get_transform_blend(), 1,
2308 Geom::NT_uint16, Geom::C_index, 0, 2);
2309 temp_format->add_array(anim_array_format);
2313 for (vi = vertex_pool->
begin(); vi != vertex_pool->
end(); ++vi) {
2316 EggMorphVertexList::const_iterator mvi;
2317 for (mvi = vertex->_dxyzs.begin(); mvi != vertex->_dxyzs.end(); ++mvi) {
2318 slider_names[(*mvi).get_name()].set_bit(vertex->
get_index());
2319 record_morph(anim_array_format, character_maker, (*mvi).
get_name(),
2320 InternalName::get_vertex(), 3);
2322 if (vertex->has_normal()) {
2323 EggMorphNormalList::const_iterator mni;
2324 for (mni = vertex->_dnormals.begin(); mni != vertex->_dnormals.end(); ++mni) {
2325 slider_names[(*mni).get_name()].set_bit(vertex->
get_index());
2326 record_morph(anim_array_format, character_maker, (*mni).
get_name(),
2327 InternalName::get_normal(), 3);
2330 if (!ignore_color && vertex->has_color()) {
2331 EggMorphColorList::const_iterator mci;
2332 for (mci = vertex->_drgbas.begin(); mci != vertex->_drgbas.end(); ++mci) {
2333 slider_names[(*mci).get_name()].set_bit(vertex->
get_index());
2334 record_morph(anim_array_format, character_maker, (*mci).
get_name(),
2335 InternalName::get_color(), 4);
2341 string name = egg_uv->get_name();
2342 bool has_w = (find(uvw_names.begin(), uvw_names.end(), name) != uvw_names.end());
2343 PT(
InternalName) iname = InternalName::get_texcoord_name(name);
2345 EggMorphTexCoordList::const_iterator mti;
2346 for (mti = egg_uv->_duvs.begin(); mti != egg_uv->_duvs.end(); ++mti) {
2347 slider_names[(*mti).get_name()].set_bit(vertex->
get_index());
2348 record_morph(anim_array_format, character_maker, (*mti).
get_name(),
2349 iname, has_w ? 3 : 2);
2354 if (!slider_names.empty()) {
2360 for (si = slider_names.begin(); si != slider_names.end(); ++si) {
2362 slider_table->add_slider(slider, (*si).second);
2368 name = character_maker->
get_name();
2371 temp_format->maybe_align_columns_for_animation();
2374 GeomVertexFormat::register_format(temp_format);
2382 vertex_data->reserve_num_rows(vertex_pool->
size());
2384 vertex_data->set_transform_blend_table(blend_table);
2385 if (slider_table !=
nullptr) {
2386 vertex_data->set_slider_table(SliderTable::register_table(slider_table));
2391 for (vi = vertex_pool->
begin(); vi != vertex_pool->
end(); ++vi) {
2400 EggMorphVertexList::const_iterator mvi;
2401 for (mvi = vertex->_dxyzs.begin(); mvi != vertex->_dxyzs.end(); ++mvi) {
2404 InternalName::get_morph(InternalName::get_vertex(), morph.get_name());
2406 gvw.
add_data3d(morph.get_offset() * transform);
2410 if (vertex->has_normal()) {
2412 LNormald orig_normal = vertex->get_normal();
2413 LNormald transformed_normal = normalize(orig_normal * transform);
2417 EggMorphNormalList::const_iterator mni;
2418 for (mni = vertex->_dnormals.begin(); mni != vertex->_dnormals.end(); ++mni) {
2421 InternalName::get_morph(InternalName::get_normal(), morph.get_name());
2423 LNormald morphed_normal = orig_normal + morph.get_offset();
2424 LNormald transformed_morphed_normal = normalize(morphed_normal * transform);
2425 LVector3d delta = transformed_morphed_normal - transformed_normal;
2431 if (!ignore_color && vertex->has_color()) {
2436 EggMorphColorList::const_iterator mci;
2437 for (mci = vertex->_drgbas.begin(); mci != vertex->_drgbas.end(); ++mci) {
2440 InternalName::get_morph(InternalName::get_color(), morph.get_name());
2450 LTexCoord3d orig_uvw = egg_uv->
get_uvw();
2451 LTexCoord3d uvw = egg_uv->
get_uvw();
2453 string name = egg_uv->get_name();
2454 PT(
InternalName) iname = InternalName::get_texcoord_name(name);
2457 BakeInUVs::const_iterator buv = render_state->_bake_in_uvs.find(iname);
2458 if (buv != render_state->_bake_in_uvs.end()) {
2460 uvw = uvw * (*buv).second->get_transform3d();
2466 EggMorphTexCoordList::const_iterator mti;
2467 for (mti = egg_uv->_duvs.begin(); mti != egg_uv->_duvs.end(); ++mti) {
2470 InternalName::get_morph(iname, morph.get_name());
2472 LTexCoord3d duvw = morph.get_offset();
2473 if (buv != render_state->_bake_in_uvs.end()) {
2474 LTexCoord3d new_uvw = orig_uvw + duvw;
2475 duvw = (new_uvw * (*buv).second->get_transform3d()) - uvw;
2483 if (egg_uv->has_tangent() && egg_uv->has_binormal()) {
2484 PT(
InternalName) iname = InternalName::get_tangent_name(name);
2487 LVector3d tangent = egg_uv->get_tangent();
2488 LVector3d binormal = egg_uv->get_binormal();
2490 gvw.
set_column(InternalName::get_binormal_name(name));
2499 LVecBase4d aux = egg_aux->
get_aux();
2501 string name = egg_aux->get_name();
2510 gvw.
set_column(InternalName::get_transform_blend());
2515 bool inserted = _vertex_pool_data.insert
2516 (VertexPoolData::value_type(vpt, vertex_data)).second;
2517 nassertr(inserted, vertex_data);
2534 for (vi = vertex_pool->
begin(); vi != vertex_pool->
end(); ++vi) {
2543 nassertr(vt !=
nullptr,
nullptr);
2548 double quantize = egg_vertex_membership_quantize;
2549 EggVertex::GroupRef::const_iterator gri;
2553 if (quantize != 0.0) {
2554 membership = cfloor(membership / quantize + 0.5) * quantize;
2558 nassertr(vt !=
nullptr,
nullptr);
2562 if (egg_vertex_max_num_joints >= 0) {
2567 int table_index = blend_table->add_blend(blend);
2584 int num_components) {
2586 InternalName::get_morph(column_name, morph_name);
2589 (delta_name, num_components,
2590 Geom::NT_stdfloat, Geom::C_morph_delta);
2602 bool has_overall_color,
const LColor &overall_color) {
2604 if (egg_prim->
is_of_type(EggPolygon::get_class_type())) {
2605 if (egg_prim->size() == 3) {
2609 }
else if (egg_prim->
is_of_type(EggTriangleStrip::get_class_type())) {
2612 }
else if (egg_prim->
is_of_type(EggTriangleFan::get_class_type())) {
2615 }
else if (egg_prim->
is_of_type(EggLine::get_class_type())) {
2616 if (egg_prim->size() == 2) {
2617 primitive =
new GeomLines(Geom::UH_static);
2622 }
else if (egg_prim->
is_of_type(EggPoint::get_class_type())) {
2625 }
else if (egg_prim->
is_of_type(EggPatch::get_class_type())) {
2626 int num_vertices = egg_prim->size();
2627 primitive =
new GeomPatches(num_vertices, Geom::UH_static);
2630 if (primitive ==
nullptr) {
2632 egg2pg_cat.warning()
2633 <<
"Ignoring " << egg_prim->get_type() <<
"\n";
2637 if (render_state->_flat_shaded) {
2638 primitive->set_shade_model(GeomPrimitive::SM_flat_first_vertex);
2640 }
else if (egg_prim->
get_shading() == EggPrimitive::S_overall) {
2641 primitive->set_shade_model(GeomPrimitive::SM_uniform);
2644 primitive->set_shade_model(GeomPrimitive::SM_smooth);
2649 PrimitiveUnifier pu(primitive);
2650 std::pair<UniquePrimitives::iterator, bool> result =
2651 unique_primitives.insert(UniquePrimitives::value_type(pu, primitive));
2653 if (result.second) {
2655 primitives.push_back(primitive);
2657 if (egg2pg_cat.is_debug()) {
2659 <<
"First primitive of type " << primitive->get_type()
2660 <<
": " << primitive <<
"\n";
2668 if (orig_prim->
get_num_vertices() + egg_prim->size() <= (
unsigned int)egg_max_indices) {
2669 primitive = orig_prim;
2671 }
else if (orig_prim != primitive) {
2673 (*result.first).second = primitive;
2675 if (egg2pg_cat.is_debug()) {
2677 <<
"Next primitive of type " << primitive->get_type()
2678 <<
": " << primitive <<
"\n";
2680 primitives.push_back(primitive);
2684 EggPrimitive::const_iterator vi;
2685 for (vi = egg_prim->begin(); vi != egg_prim->end(); ++vi) {
2686 primitive->add_vertex((*vi)->get_index());
2688 primitive->close_primitive();
2698 PT(
EggPolygon) poly = find_first_polygon(egg_group);
2699 if (poly !=
nullptr) {
2702 EggPolygon::const_iterator vi;
2703 for (vi = poly->begin(); vi != poly->end(); ++vi) {
2704 LVertexd vert = (*vi)->
get_pos3() * mat;
2715 PT(
EggPolygon) poly = find_first_polygon(egg_group);
2716 if (poly !=
nullptr) {
2717 if (poly->size() != 4) {
2719 <<
"Invalid number of vertices for " << egg_group->get_name() <<
"\n";
2723 LPoint3d v0 = (*poly)[0]->get_pos3() * mat;
2724 LPoint3d v1 = (*poly)[1]->get_pos3() * mat;
2725 LPoint3d v2 = (*poly)[2]->get_pos3() * mat;
2726 LPoint3d v3 = (*poly)[3]->get_pos3() * mat;
2728 LCAST(PN_stdfloat, v1),
2729 LCAST(PN_stdfloat, v2),
2730 LCAST(PN_stdfloat, v3));
2743 find_first_polygon(
EggGroup *egg_group) {
2745 EggGroup::const_iterator ci;
2746 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2747 if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
2754 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2755 if ((*ci)->is_of_type(EggGroup::get_class_type())) {
2757 PT(
EggPolygon) found = find_first_polygon(child_group);
2758 if (found !=
nullptr) {
2774 make_sphere(
EggGroup *egg_group, EggGroup::CollideFlags flags,
2775 LPoint3 ¢er, PN_stdfloat &radius, LColor &color) {
2776 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
2777 if (geom_group !=
nullptr) {
2781 EggGroup::const_iterator ci;
2782 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
2783 if ((*ci)->is_of_type(EggPrimitive::get_class_type())) {
2785 EggPrimitive::const_iterator pi;
2786 for (pi = prim->begin(); pi != prim->end(); ++pi) {
2787 vertices.insert(*pi);
2793 int num_vertices = 0;
2794 LPoint3d d_center(0.0, 0.0, 0.0);
2797 for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
2803 if (num_vertices > 0) {
2804 d_center /= (double)num_vertices;
2808 double radius2 = 0.0;
2809 for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
2812 LVector3d v = p3 - d_center;
2813 radius2 = max(radius2, v.length_squared());
2816 center = LCAST(PN_stdfloat, d_center);
2817 radius = sqrtf(radius2);
2820 vi = vertices.begin();
2834 make_box(
EggGroup *egg_group, EggGroup::CollideFlags flags,
2835 const LMatrix4 &xform, LPoint3 &min_p, LPoint3 &max_p) {
2836 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
2837 if (geom_group !=
nullptr) {
2841 EggGroup::const_iterator ci;
2842 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
2843 if ((*ci)->is_of_type(EggPrimitive::get_class_type())) {
2845 EggPrimitive::const_iterator pi;
2846 for (pi = prim->begin(); pi != prim->end(); ++pi) {
2847 vertices.insert(*pi);
2854 vi = vertices.begin();
2856 if (vi == vertices.end()) {
2864 LPoint3 min_pd = LCAST(PN_stdfloat, vertex->
get_pos3()) * xform;
2865 LPoint3 max_pd = min_pd;
2867 for (++vi; vi != vertices.end(); ++vi) {
2869 LPoint3 pos = LCAST(PN_stdfloat, vertex->
get_pos3()) * xform;
2870 min_pd.set(min(min_pd[0], pos[0]),
2871 min(min_pd[1], pos[1]),
2872 min(min_pd[2], pos[2]));
2873 max_pd.set(max(max_pd[0], pos[0]),
2874 max(max_pd[1], pos[1]),
2875 max(max_pd[2], pos[2]));
2880 return (min_pd != max_pd);
2890 make_box(
EggGroup *egg_group, EggGroup::CollideFlags flags,
2891 LPoint3 &min_p, LPoint3 &max_p, LColor &color) {
2893 color.set(1.0, 1.0, 1.0, 1.0);
2894 return make_box(egg_group, flags, LMatrix4::ident_mat(), min_p, max_p);
2904 if (egg_group->get_cs_type() != EggGroup::CST_none) {
2905 start_group = egg_group;
2908 switch (start_group->get_cs_type()) {
2909 case EggGroup::CST_none:
2913 case EggGroup::CST_plane:
2914 make_collision_plane(egg_group, cnode, start_group->get_collide_flags());
2917 case EggGroup::CST_polygon:
2918 make_collision_polygon(egg_group, cnode, start_group->get_collide_flags());
2921 case EggGroup::CST_polyset:
2922 make_collision_polyset(egg_group, cnode, start_group->get_collide_flags());
2925 case EggGroup::CST_sphere:
2926 make_collision_sphere(egg_group, cnode, start_group->get_collide_flags());
2929 case EggGroup::CST_box:
2930 make_collision_box(egg_group, cnode, start_group->get_collide_flags());
2933 case EggGroup::CST_inv_sphere:
2934 make_collision_inv_sphere(egg_group, cnode, start_group->get_collide_flags());
2937 case EggGroup::CST_tube:
2938 make_collision_capsule(egg_group, cnode, start_group->get_collide_flags());
2941 case EggGroup::CST_floor_mesh:
2942 make_collision_floor_mesh(egg_group, cnode, start_group->get_collide_flags());
2946 if ((start_group->get_collide_flags() & EggGroup::CF_descend) != 0) {
2948 EggGroup::const_iterator ci;
2949 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2950 if ((*ci)->is_of_type(EggGroup::get_class_type())) {
2951 make_collision_solids(start_group, DCAST(
EggGroup, *ci), cnode);
2955 egg2pg_cat.warning()
2956 <<
"Using <Collide> without 'descend' is deprecated. 'descend' "
2957 <<
"will become the default in a future version of Panda3D.\n";
2967 EggGroup::CollideFlags flags) {
2968 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
2969 if (geom_group !=
nullptr) {
2970 EggGroup::const_iterator ci;
2971 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
2972 if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
2974 create_collision_plane(DCAST(
EggPolygon, *ci), egg_group);
2975 if (csplane !=
nullptr) {
2976 apply_collision_flags(csplane, flags);
2977 csplane->
xform(cnode->get_transform()->get_mat());
2981 }
else if ((*ci)->is_of_type(EggCompositePrimitive::get_class_type())) {
2985 make_collision_plane(temp_group, cnode, flags);
3001 EggGroup::CollideFlags flags) {
3003 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
3006 if (geom_group !=
nullptr) {
3007 create_collision_floor_mesh(cnode, geom_group,flags);
3017 EggGroup::CollideFlags flags) {
3019 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
3020 if (geom_group !=
nullptr) {
3021 EggGroup::const_iterator ci;
3022 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
3023 if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
3024 create_collision_polygons(cnode, DCAST(
EggPolygon, *ci),
3026 }
else if ((*ci)->is_of_type(EggCompositePrimitive::get_class_type())) {
3030 make_collision_polygon(temp_group, cnode, flags);
3045 EggGroup::CollideFlags flags) {
3046 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
3047 if (geom_group !=
nullptr) {
3048 EggGroup::const_iterator ci;
3049 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
3050 if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
3051 create_collision_polygons(cnode, DCAST(
EggPolygon, *ci),
3053 }
else if ((*ci)->is_of_type(EggCompositePrimitive::get_class_type())) {
3057 make_collision_polyset(temp_group, cnode, flags);
3070 EggGroup::CollideFlags flags) {
3074 if (make_sphere(egg_group, flags, center, radius, dummycolor)) {
3077 apply_collision_flags(cssphere, flags);
3078 cssphere->xform(cnode->get_transform()->get_mat());
3089 EggGroup::CollideFlags flags) {
3093 if (make_box(egg_group, flags, transform->get_mat(), min_p, max_p)) {
3096 apply_collision_flags(csbox, flags);
3107 EggGroup::CollideFlags flags) {
3111 if (make_sphere(egg_group, flags, center, radius, dummycolor)) {
3114 apply_collision_flags(cssphere, flags);
3115 cssphere->xform(cnode->get_transform()->get_mat());
3126 EggGroup::CollideFlags flags) {
3127 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
3128 if (geom_group !=
nullptr) {
3132 EggGroup::const_iterator ci;
3133 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
3134 if ((*ci)->is_of_type(EggPrimitive::get_class_type())) {
3136 EggPrimitive::const_iterator pi;
3137 for (pi = prim->begin(); pi != prim->end(); ++pi) {
3138 vertices.insert(*pi);
3145 size_t num_vertices = vertices.size();
3146 if (num_vertices != 0) {
3148 vpos.reserve(num_vertices);
3150 LPoint3d center(0.0, 0.0, 0.0);
3152 for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
3154 const LPoint3d &pos = vtx->
get_pos3();
3155 vpos.push_back(pos);
3158 center /= (double)num_vertices;
3164 double radius2 = 0.0;
3165 LPoint3d far_a = center;
3166 for (i = 0; i < num_vertices; i++) {
3167 double dist2 = (vpos[i] - center).length_squared();
3168 if (dist2 > radius2) {
3178 LPoint3d far_b = center;
3179 for (i = 0; i < num_vertices; i++) {
3180 double dist2 = (vpos[i] - far_a).length_squared();
3181 if (dist2 > radius2) {
3198 LPoint3d cap_a_center(0.0, 0.0, 0.0);
3199 LPoint3d cap_b_center(0.0, 0.0, 0.0);
3205 double center_length = (far_a - far_b).length() / 4.0;
3206 double center_length2 = center_length * center_length;
3208 for (i = 0; i < num_vertices; i++) {
3209 double dist2 = (vpos[i] - center).length_squared();
3210 if (dist2 > center_length2) {
3213 double dist_a2 = (vpos[i] - far_a).length_squared();
3214 double dist_b2 = (vpos[i] - far_b).length_squared();
3215 if (dist_a2 < dist_b2) {
3217 cap_a_center += vpos[i];
3221 cap_b_center += vpos[i];
3227 if (num_a > 0 && num_b > 0) {
3228 cap_a_center /= (double)num_a;
3229 cap_b_center /= (double)num_b;
3233 LVector3d axis = cap_b_center - cap_a_center;
3238 if (IS_THRESHOLD_ZERO(axis[0], 0.01)) {
3241 if (IS_THRESHOLD_ZERO(axis[1], 0.01)) {
3244 if (IS_THRESHOLD_ZERO(axis[2], 0.01)) {
3256 look_at(mat, axis, LVector3d(0.0, 0.0, 1.0), CS_zup_right);
3257 mat.set_row(3, center);
3259 inv_mat.invert_from(mat);
3261 for (i = 0; i < num_vertices; i++) {
3262 vpos[i] = vpos[i] * inv_mat;
3265 double max_radius2 = 0.0;
3268 for (i = 0; i < num_vertices; i++) {
3269 LVector2d v(vpos[i][0], vpos[i][2]);
3270 double radius2 = v.length_squared();
3271 if (radius2 > max_radius2) {
3272 max_radius2 = radius2;
3282 for (i = 0; i < num_vertices; i++) {
3283 LVector2d v(vpos[i][0], vpos[i][2]);
3284 double radius2 = v.length_squared();
3286 if (vpos[i][1] < min_y) {
3289 double factor = sqrt(max_radius2 - radius2);
3290 min_y = min(min_y, vpos[i][1] + factor);
3292 }
else if (vpos[i][1] > max_y) {
3293 double factor = sqrt(max_radius2 - radius2);
3294 max_y = max(max_y, vpos[i][1] - factor);
3298 double length = max_y - min_y;
3299 double radius = sqrt(max_radius2);
3302 LVector3d half = axis * (length / 2.0);
3303 LPoint3d point_a = center - half;
3304 LPoint3d point_b = center + half;
3307 new CollisionCapsule(LCAST(PN_stdfloat, point_a), LCAST(PN_stdfloat, point_b),
3309 apply_collision_flags(cscapsule, flags);
3310 cscapsule->xform(cnode->get_transform()->get_mat());
3322 apply_collision_flags(
CollisionSolid *solid, EggGroup::CollideFlags flags) {
3323 if ((flags & EggGroup::CF_intangible) != 0) {
3326 if ((flags & EggGroup::CF_level) != 0) {
3336 find_collision_geometry(
EggGroup *egg_group, EggGroup::CollideFlags flags) {
3337 if ((flags & EggGroup::CF_descend) != 0) {
3344 EggGroup::const_iterator ci;
3345 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
3346 if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
3354 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
3355 if ((*ci)->is_of_type(EggGroup::get_class_type())) {
3357 if (child_group->get_cs_type() == egg_group->get_cs_type()) {
3374 <<
"Ignoring degenerate collision plane in " << parent_group->get_name()
3380 egg2pg_cat.warning()
3381 <<
"Non-planar polygon defining collision plane in "
3382 << parent_group->get_name()
3387 if (!egg_poly->empty()) {
3388 EggPolygon::const_iterator vi;
3389 vi = egg_poly->begin();
3391 LVertexd vert = (*vi)->get_pos3();
3392 vertices.push_back(LCAST(PN_stdfloat, vert));
3394 LVertexd last_vert = vert;
3396 while (vi != egg_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) {
3410 LPlane plane(vertices[0], vertices[1], vertices[2]);
3421 EggGroup::CollideFlags flags) {
3427 <<
"Ignoring degenerate collision polygon in "
3428 << parent_group->get_name()
3433 if (group->size() != 1) {
3435 <<
"Triangulating concave or non-planar collision polygon in "
3436 << parent_group->get_name()
3440 EggGroup::iterator ci;
3441 for (ci = group->begin(); ci != group->end(); ++ci) {
3445 if (!poly->empty()) {
3446 EggPolygon::const_iterator vi;
3449 LVertexd vert = (*vi)->get_pos3();
3450 vertices.push_back(LCAST(PN_stdfloat, vert));
3452 LVertexd last_vert = vert;
3454 while (vi != poly->end()) {
3455 vert = (*vi)->get_pos3();
3456 if (!vert.almost_equal(last_vert)) {
3457 vertices.push_back(LCAST(PN_stdfloat, vert));
3465 if (vertices.size() >= 3) {
3466 const LVertex *vertices_begin = &vertices[0];
3467 const LVertex *vertices_end = vertices_begin + vertices.size();
3470 if (cspoly->is_valid()) {
3471 apply_collision_flags(cspoly, flags);
3472 cspoly->xform(cnode->get_transform()->get_mat());
3486 EggGroup::CollideFlags flags) {
3490 pool.local_object();
3491 EggGroup::const_iterator egi;
3492 for (egi = parent_group->begin(); egi != parent_group->end(); ++egi) {
3493 if ((*egi)->is_of_type(EggPolygon::get_class_type())) {
3497 <<
"Ignoring degenerate collision polygon in "
3498 << parent_group->get_name()
3505 if(group->size() == 0) {
3507 <<
"empty collision solid\n";
3513 EggGroup::iterator ci;
3514 for (ci = group->begin(); ci != group->end(); ++ci) {
3516 if (poly->get_num_vertices() == 3) {
3517 CollisionFloorMesh::TriangleIndices tri;
3520 tri.p1=pool.create_unique_vertex(*poly->
get_vertex(0))->get_index();
3521 tri.p2=pool.create_unique_vertex(*poly->
get_vertex(1))->get_index();
3522 tri.p3=pool.create_unique_vertex(*poly->
get_vertex(2))->get_index();
3524 triangles.push_back(tri);
3525 }
else if (poly->get_num_vertices() == 4) {
3528 CollisionFloorMesh::TriangleIndices tri;
3529 CollisionFloorMesh::TriangleIndices tri2;
3532 tri.p1=pool.create_unique_vertex(*poly->
get_vertex(0))->get_index();
3533 tri.p2=pool.create_unique_vertex(*poly->
get_vertex(1))->get_index();
3534 tri.p3=pool.create_unique_vertex(*poly->
get_vertex(2))->get_index();
3536 triangles.push_back(tri);
3541 tri2.p3=pool.create_unique_vertex(*poly->
get_vertex(3))->get_index();
3544 triangles.push_back(tri2);
3553 for (vi = pool.begin(); vi != pool.end(); vi++) {
3554 csfloor->add_vertex(LCAST(PN_stdfloat,(*vi)->get_pos3()));
3559 for (ti = triangles.begin(); ti != triangles.end(); ti++) {
3560 CollisionFloorMesh::TriangleIndices triangle = *ti;
3561 csfloor->add_triangle(triangle.p1, triangle.p2, triangle.p3);
3563 csfloor->xform(cnode->get_transform()->get_mat());
3577 DeferredNodes::const_iterator dni;
3578 dni = _deferred_nodes.find(node);
3580 if (dni != _deferred_nodes.end()) {
3586 next_prop.apply_to_node(node);
3589 for (
int i = 0; i < num_children; i++) {
3590 apply_deferred_nodes(node->
get_child(i), next_prop);
3603 expand_all_object_types(
EggNode *egg_node) {
3604 if (egg_node->
is_of_type(EggGroup::get_class_type())) {
3607 if (egg_group->get_num_object_types() != 0) {
3610 if (!expand_object_types(egg_group, expanded, expanded_history)) {
3618 if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
3620 EggGroupNode::const_iterator ci;
3621 ci = egg_group_node->begin();
3622 while (ci != egg_group_node->end()) {
3623 EggGroupNode::const_iterator cnext = ci;
3626 if (!expand_all_object_types(*ci)) {
3628 egg_group_node->erase(ci);
3649 int num_object_types = egg_group->get_num_object_types();
3652 vector_string object_types;
3654 for (i = 0; i < num_object_types; i++) {
3655 object_types.push_back(egg_group->get_object_type(i));
3657 egg_group->clear_object_types();
3659 for (i = 0; i < num_object_types; i++) {
3660 string object_type = object_types[i];
3664 if (!new_expanded.insert(object_type).second) {
3666 <<
"Cycle in ObjectType expansions:\n";
3668 for (pi = expanded_history.begin();
3669 pi != expanded_history.end();
3671 egg2pg_cat.error(
false)
3674 egg2pg_cat.error(
false) << object_type <<
"\n";
3680 new_expanded_history.push_back(object_type);
3682 if (!do_expand_object_type(egg_group, new_expanded,
3683 new_expanded_history, object_type)) {
3699 const string &object_type) {
3704 (
"egg-object-type-" +
downcase(object_type),
"");
3705 string egg_syntax = egg_object_type;
3707 if (!egg_object_type.has_value()) {
3710 if (cmp_nocase_uh(object_type,
"barrier") == 0) {
3711 egg_syntax =
"<Collide> { Polyset descend }";
3713 }
else if (cmp_nocase_uh(object_type,
"solidpoly") == 0) {
3714 egg_syntax =
"<Collide> { Polyset descend solid }";
3716 }
else if (cmp_nocase_uh(object_type,
"turnstile") == 0) {
3717 egg_syntax =
"<Collide> { Polyset descend turnstile }";
3719 }
else if (cmp_nocase_uh(object_type,
"sphere") == 0) {
3720 egg_syntax =
"<Collide> { Sphere descend }";
3722 }
else if (cmp_nocase_uh(object_type,
"tube") == 0) {
3723 egg_syntax =
"<Collide> { Tube descend }";
3725 }
else if (cmp_nocase_uh(object_type,
"trigger") == 0) {
3726 egg_syntax =
"<Collide> { Polyset descend intangible }";
3728 }
else if (cmp_nocase_uh(object_type,
"trigger_sphere") == 0) {
3729 egg_syntax =
"<Collide> { Sphere descend intangible }";
3731 }
else if (cmp_nocase_uh(object_type,
"eye_trigger") == 0) {
3732 egg_syntax =
"<Collide> { Polyset descend intangible center }";
3734 }
else if (cmp_nocase_uh(object_type,
"bubble") == 0) {
3735 egg_syntax =
"<Collide> { Sphere keep descend }";
3737 }
else if (cmp_nocase_uh(object_type,
"ghost") == 0) {
3738 egg_syntax =
"<Scalar> collide-mask { 0 }";
3740 }
else if (cmp_nocase_uh(object_type,
"dcs") == 0) {
3741 egg_syntax =
"<DCS> { 1 }";
3743 }
else if (cmp_nocase_uh(object_type,
"model") == 0) {
3744 egg_syntax =
"<Model> { 1 }";
3746 }
else if (cmp_nocase_uh(object_type,
"none") == 0) {
3750 }
else if (cmp_nocase_uh(object_type,
"backstage") == 0) {
3756 <<
"Unknown ObjectType " << object_type <<
"\n";
3758 egg2pg_cat.debug() <<
"returning true\n";
3763 if (!egg_syntax.empty()) {
3764 if (!egg_group->
parse_egg(egg_syntax)) {
3766 <<
"Error while parsing definition for ObjectType "
3767 << object_type <<
"\n";
3773 if (egg_group->get_num_object_types() != 0) {
3774 if (!expand_object_types(egg_group, expanded, expanded_history)) {
3788 TextureStage::CombineMode EggLoader::
3790 EggTexture::CombineChannel channel) {
3791 switch (egg_tex->get_combine_mode(channel)) {
3792 case EggTexture::CM_unspecified:
3795 case EggTexture::CM_modulate:
3796 return TextureStage::CM_modulate;
3798 case EggTexture::CM_replace:
3799 return TextureStage::CM_replace;
3801 case EggTexture::CM_add:
3802 return TextureStage::CM_add;
3804 case EggTexture::CM_add_signed:
3805 return TextureStage::CM_add_signed;
3807 case EggTexture::CM_interpolate:
3808 return TextureStage::CM_interpolate;
3810 case EggTexture::CM_subtract:
3811 return TextureStage::CM_subtract;
3813 case EggTexture::CM_dot3_rgb:
3814 return TextureStage::CM_dot3_rgb;
3816 case EggTexture::CM_dot3_rgba:
3817 return TextureStage::CM_dot3_rgba;
3820 return TextureStage::CM_undefined;
3827 TextureStage::CombineSource EggLoader::
3828 get_combine_source(
const EggTexture *egg_tex,
3829 EggTexture::CombineChannel channel,
int n) {
3830 switch (egg_tex->get_combine_source(channel, n)) {
3831 case EggTexture::CS_unspecified:
3836 return TextureStage::CS_previous;
3838 return TextureStage::CS_texture;
3840 return TextureStage::CS_constant;
3844 case EggTexture::CS_texture:
3845 return TextureStage::CS_texture;
3847 case EggTexture::CS_constant:
3848 return TextureStage::CS_constant;
3850 case EggTexture::CS_primary_color:
3851 return TextureStage::CS_primary_color;
3853 case EggTexture::CS_previous:
3854 return TextureStage::CS_previous;
3856 case EggTexture::CS_constant_color_scale:
3857 return TextureStage::CS_constant_color_scale;
3859 case EggTexture::CS_last_saved_result:
3860 return TextureStage::CS_last_saved_result;
3863 return TextureStage::CS_undefined;
3870 TextureStage::CombineOperand EggLoader::
3871 get_combine_operand(
const EggTexture *egg_tex,
3872 EggTexture::CombineChannel channel,
int n) {
3873 switch (egg_tex->get_combine_operand(channel, n)) {
3874 case EggTexture::CO_unspecified:
3875 if (channel == EggTexture::CC_rgb) {
3878 return n < 2 ? TextureStage::CO_src_color : TextureStage::CO_src_alpha;
3881 return TextureStage::CO_src_alpha;
3884 case EggTexture::CO_src_color:
3885 return TextureStage::CO_src_color;
3887 case EggTexture::CO_one_minus_src_color:
3888 return TextureStage::CO_one_minus_src_color;
3890 case EggTexture::CO_src_alpha:
3891 return TextureStage::CO_src_alpha;
3893 case EggTexture::CO_one_minus_src_alpha:
3894 return TextureStage::CO_one_minus_src_alpha;
3897 return TextureStage::CO_undefined;
3904 ColorBlendAttrib::Mode EggLoader::
3905 get_color_blend_mode(EggGroup::BlendMode mode) {
3907 case EggGroup::BM_unspecified:
3908 case EggGroup::BM_none:
3909 return ColorBlendAttrib::M_none;
3910 case EggGroup::BM_add:
3911 return ColorBlendAttrib::M_add;
3912 case EggGroup::BM_subtract:
3913 return ColorBlendAttrib::M_subtract;
3914 case EggGroup::BM_inv_subtract:
3915 return ColorBlendAttrib::M_inv_subtract;
3916 case EggGroup::BM_min:
3917 return ColorBlendAttrib::M_min;
3918 case EggGroup::BM_max:
3919 return ColorBlendAttrib::M_max;
3922 return ColorBlendAttrib::M_none;
3929 ColorBlendAttrib::Operand EggLoader::
3930 get_color_blend_operand(EggGroup::BlendOperand operand) {
3932 case EggGroup::BO_zero:
3933 return ColorBlendAttrib::O_zero;
3934 case EggGroup::BO_unspecified:
3935 case EggGroup::BO_one:
3936 return ColorBlendAttrib::O_one;
3937 case EggGroup::BO_incoming_color:
3938 return ColorBlendAttrib::O_incoming_color;
3939 case EggGroup::BO_one_minus_incoming_color:
3940 return ColorBlendAttrib::O_one_minus_incoming_color;
3941 case EggGroup::BO_fbuffer_color:
3942 return ColorBlendAttrib::O_fbuffer_color;
3943 case EggGroup::BO_one_minus_fbuffer_color:
3944 return ColorBlendAttrib::O_one_minus_fbuffer_color;
3945 case EggGroup::BO_incoming_alpha:
3946 return ColorBlendAttrib::O_incoming_alpha;
3947 case EggGroup::BO_one_minus_incoming_alpha:
3948 return ColorBlendAttrib::O_one_minus_incoming_alpha;
3949 case EggGroup::BO_fbuffer_alpha:
3950 return ColorBlendAttrib::O_fbuffer_alpha;
3951 case EggGroup::BO_one_minus_fbuffer_alpha:
3952 return ColorBlendAttrib::O_one_minus_fbuffer_alpha;
3953 case EggGroup::BO_constant_color:
3954 return ColorBlendAttrib::O_constant_color;
3955 case EggGroup::BO_one_minus_constant_color:
3956 return ColorBlendAttrib::O_one_minus_constant_color;
3957 case EggGroup::BO_constant_alpha:
3958 return ColorBlendAttrib::O_constant_alpha;
3959 case EggGroup::BO_one_minus_constant_alpha:
3960 return ColorBlendAttrib::O_one_minus_constant_alpha;
3961 case EggGroup::BO_incoming_color_saturate:
3962 return ColorBlendAttrib::O_incoming_color_saturate;
3963 case EggGroup::BO_color_scale:
3964 return ColorBlendAttrib::O_color_scale;
3965 case EggGroup::BO_one_minus_color_scale:
3966 return ColorBlendAttrib::O_one_minus_color_scale;
3967 case EggGroup::BO_alpha_scale:
3968 return ColorBlendAttrib::O_alpha_scale;
3969 case EggGroup::BO_one_minus_alpha_scale:
3970 return ColorBlendAttrib::O_one_minus_alpha_scale;
3973 return ColorBlendAttrib::O_zero;
3979 bool EggLoader::VertexPoolTransform::
3980 operator < (
const EggLoader::VertexPoolTransform &other)
const {
3981 if (_vertex_pool != other._vertex_pool) {
3982 return _vertex_pool < other._vertex_pool;
3984 int compare = _transform.compare_to(other._transform, 0.001);
3989 if (_bake_in_uvs.size() != other._bake_in_uvs.size()) {
3990 return _bake_in_uvs.size() < other._bake_in_uvs.size();
3993 BakeInUVs::const_iterator ai, bi;
3994 ai = _bake_in_uvs.begin();
3995 bi = other._bake_in_uvs.begin();
3996 while (ai != _bake_in_uvs.end()) {
3997 nassertr(bi != other._bake_in_uvs.end(),
false);
3998 if ((*ai) != (*bi)) {
3999 return (*ai) < (*bi);
4004 nassertr(bi == other._bake_in_uvs.end(),
false);