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_emission:
1544 stage->set_mode(TextureStage::M_emission);
1547 case EggTexture::ET_unspecified:
1551 switch (egg_tex->get_combine_mode(EggTexture::CC_rgb)) {
1552 case EggTexture::CM_replace:
1553 stage->set_combine_rgb(get_combine_mode(egg_tex, EggTexture::CC_rgb),
1554 get_combine_source(egg_tex, EggTexture::CC_rgb, 0),
1555 get_combine_operand(egg_tex, EggTexture::CC_rgb, 0));
1558 case EggTexture::CM_modulate:
1559 case EggTexture::CM_add:
1560 case EggTexture::CM_add_signed:
1561 case EggTexture::CM_subtract:
1562 case EggTexture::CM_dot3_rgb:
1563 case EggTexture::CM_dot3_rgba:
1564 stage->set_combine_rgb(get_combine_mode(egg_tex, EggTexture::CC_rgb),
1565 get_combine_source(egg_tex, EggTexture::CC_rgb, 0),
1566 get_combine_operand(egg_tex, EggTexture::CC_rgb, 0),
1567 get_combine_source(egg_tex, EggTexture::CC_rgb, 1),
1568 get_combine_operand(egg_tex, EggTexture::CC_rgb, 1));
1571 case EggTexture::CM_interpolate:
1572 stage->set_combine_rgb(get_combine_mode(egg_tex, EggTexture::CC_rgb),
1573 get_combine_source(egg_tex, EggTexture::CC_rgb, 0),
1574 get_combine_operand(egg_tex, EggTexture::CC_rgb, 0),
1575 get_combine_source(egg_tex, EggTexture::CC_rgb, 1),
1576 get_combine_operand(egg_tex, EggTexture::CC_rgb, 1),
1577 get_combine_source(egg_tex, EggTexture::CC_rgb, 2),
1578 get_combine_operand(egg_tex, EggTexture::CC_rgb, 2));
1581 case EggTexture::CM_unspecified:
1585 switch (egg_tex->get_combine_mode(EggTexture::CC_alpha)) {
1586 case EggTexture::CM_replace:
1587 stage->set_combine_alpha(get_combine_mode(egg_tex, EggTexture::CC_alpha),
1588 get_combine_source(egg_tex, EggTexture::CC_alpha, 0),
1589 get_combine_operand(egg_tex, EggTexture::CC_alpha, 0));
1592 case EggTexture::CM_modulate:
1593 case EggTexture::CM_add:
1594 case EggTexture::CM_add_signed:
1595 case EggTexture::CM_subtract:
1596 stage->set_combine_alpha(get_combine_mode(egg_tex, EggTexture::CC_alpha),
1597 get_combine_source(egg_tex, EggTexture::CC_alpha, 0),
1598 get_combine_operand(egg_tex, EggTexture::CC_alpha, 0),
1599 get_combine_source(egg_tex, EggTexture::CC_alpha, 1),
1600 get_combine_operand(egg_tex, EggTexture::CC_alpha, 1));
1603 case EggTexture::CM_interpolate:
1604 stage->set_combine_alpha(get_combine_mode(egg_tex, EggTexture::CC_alpha),
1605 get_combine_source(egg_tex, EggTexture::CC_alpha, 0),
1606 get_combine_operand(egg_tex, EggTexture::CC_alpha, 0),
1607 get_combine_source(egg_tex, EggTexture::CC_alpha, 1),
1608 get_combine_operand(egg_tex, EggTexture::CC_alpha, 1),
1609 get_combine_source(egg_tex, EggTexture::CC_alpha, 2),
1610 get_combine_operand(egg_tex, EggTexture::CC_alpha, 2));
1613 case EggTexture::CM_unspecified:
1614 case EggTexture::CM_dot3_rgb:
1615 case EggTexture::CM_dot3_rgba:
1622 InternalName::get_texcoord_name(egg_tex->
get_uv_name());
1623 stage->set_texcoord_name(name);
1655 separate_switches(
EggNode *egg_node) {
1656 bool parent_has_switch =
false;
1657 if (egg_node->
is_of_type(EggGroup::get_class_type())) {
1659 parent_has_switch = egg_group->get_switch_flag();
1662 if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
1665 EggGroupNode::iterator ci;
1666 ci = egg_group->begin();
1667 while (ci != egg_group->end()) {
1668 EggGroupNode::iterator cnext;
1673 if (parent_has_switch &&
1674 child->is_of_type(EggPrimitive::get_class_type())) {
1677 egg_group->
replace(ci, new_group.p());
1678 new_group->add_child(child);
1681 separate_switches(child);
1694 emulate_bface(
EggNode *egg_node) {
1695 if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
1699 EggGroupNode::iterator ci;
1700 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1702 if (child->is_of_type(EggPolygon::get_class_type())) {
1708 dup_poly->reverse_vertex_ordering();
1709 if (dup_poly->has_normal()) {
1710 dup_poly->set_normal(-dup_poly->get_normal());
1714 EggPolygon::iterator vi;
1715 for (vi = dup_poly->begin(); vi != dup_poly->end(); ++vi) {
1717 if (vertex->has_normal()) {
1719 dup_vertex.set_normal(-dup_vertex.get_normal());
1721 if (new_vertex != vertex) {
1723 dup_poly->replace(vi, new_vertex);
1727 dup_prims->add_child(dup_poly);
1731 emulate_bface(child);
1745 if (egg_node->
is_of_type(EggBin::get_class_type())) {
1746 return make_node(DCAST(
EggBin, egg_node), parent);
1747 }
else if (egg_node->
is_of_type(EggGroup::get_class_type())) {
1748 return make_node(DCAST(
EggGroup, egg_node), parent);
1749 }
else if (egg_node->
is_of_type(EggTable::get_class_type())) {
1750 return make_node(DCAST(
EggTable, egg_node), parent);
1751 }
else if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
1752 return make_node(DCAST(
EggGroupNode, egg_node), parent);
1766 switch (egg_bin->get_bin_number()) {
1767 case EggBinner::BN_polyset:
1768 case EggBinner::BN_patches:
1769 make_polyset(egg_bin, parent,
nullptr, _dynamic_override, _dynamic_override_char_maker);
1772 case EggBinner::BN_lod:
1773 return make_lod(egg_bin, parent);
1775 case EggBinner::BN_nurbs_surface:
1777 nassertr(!egg_bin->empty(),
nullptr);
1780 DCAST_INTO_R(egg_nurbs, child,
nullptr);
1782 make_nurbs_surface(egg_nurbs, parent, mat);
1786 case EggBinner::BN_nurbs_curve:
1788 nassertr(!egg_bin->empty(),
nullptr);
1791 DCAST_INTO_R(egg_nurbs, child,
nullptr);
1793 make_nurbs_curve(egg_nurbs, parent, mat);
1797 case EggBinner::BN_none:
1810 PT(
LODNode) lod_node = LODNode::make_default_lod(egg_bin->get_name());
1814 EggGroup::const_iterator ci;
1815 for (ci = egg_bin->begin(); ci != egg_bin->end(); ++ci) {
1816 LODInstance instance(*ci);
1817 instances.push_back(instance);
1822 sort(instances.begin(), instances.end());
1824 if (!instances.empty()) {
1827 lod_node->set_center(LCAST(PN_stdfloat, instances[0]._d->_center));
1830 for (
size_t i = 0; i < instances.size(); i++) {
1832 const LODInstance &instance = instances[i];
1833 make_node(instance._egg_node, lod_node);
1837 nassertr(lod_node->get_center().almost_equal
1838 (LCAST(PN_stdfloat, instance._d->_center), 0.01),
nullptr);
1841 lod_node->add_switch(instance._d->_switch_in, instance._d->_switch_out);
1844 _groups[egg_bin] = lod_node;
1845 return create_group_arc(egg_bin, parent, lod_node);
1855 if (egg_group->get_dart_type() != EggGroup::DT_none) {
1857 bool structured = (egg_group->get_dart_type() == EggGroup::DT_structured);
1861 node = char_maker.make_node();
1865 _dynamic_override =
true;
1866 _dynamic_override_char_maker = &char_maker;
1867 EggGroup::const_iterator ci;
1868 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1869 make_node(*ci, node);
1871 _dynamic_override_char_maker =
nullptr;
1872 _dynamic_override =
false;
1875 }
else if (egg_group->get_cs_type() != EggGroup::CST_none) {
1881 node->set_transform(TransformState::make_mat(LCAST(PN_stdfloat, egg_group->
get_vertex_to_node())));
1882 make_collision_solids(egg_group, egg_group, (
CollisionNode *)node.p());
1883 node->clear_transform();
1885 if ((egg_group->get_collide_flags() & EggGroup::CF_keep) != 0) {
1890 parent->add_child(combined);
1891 combined->add_child(node);
1894 EggGroup::const_iterator ci;
1895 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1896 make_node(*ci, combined);
1900 node = create_group_arc(egg_group, parent, node);
1903 }
else if (egg_group->get_portal_flag()) {
1910 set_portal_polygon(egg_group, pnode);
1912 egg2pg_cat.warning()
1913 <<
"Portal " << egg_group->get_name() <<
" has no vertices!\n";
1916 }
else if (egg_group->get_occluder_flag()) {
1923 set_occluder_polygon(egg_group, pnode);
1925 egg2pg_cat.warning()
1926 <<
"Occluder " << egg_group->get_name() <<
" has no vertices!\n";
1929 }
else if (egg_group->get_polylight_flag()) {
1937 if (!make_sphere(egg_group, EggGroup::CF_none, center, radius, color)) {
1938 egg2pg_cat.warning()
1939 <<
"Polylight " << egg_group->get_name() <<
" make_sphere failed!\n";
1950 }
else if (egg_group->get_switch_flag()) {
1951 if (egg_group->get_switch_fps() != 0.0) {
1954 ((
SequenceNode *)node.p())->set_frame_rate(egg_group->get_switch_fps());
1955 _sequences.insert(node);
1958 node =
new SwitchNode(egg_group->get_name());
1961 EggGroup::const_iterator ci;
1962 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1963 make_node(*ci, node);
1965 }
else if (egg_group->has_scrolling_uvs()) {
1966 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());
1968 EggGroup::const_iterator ci;
1969 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1970 make_node(*ci, node);
1973 }
else if (egg_group->get_model_flag() || egg_group->
has_dcs_type()) {
1975 node =
new ModelNode(egg_group->get_name());
1976 switch (egg_group->get_dcs_type()) {
1977 case EggGroup::DC_net:
1978 DCAST(
ModelNode, node)->set_preserve_transform(ModelNode::PT_net);
1981 case EggGroup::DC_no_touch:
1982 DCAST(
ModelNode, node)->set_preserve_transform(ModelNode::PT_no_touch);
1985 case EggGroup::DC_local:
1986 case EggGroup::DC_default:
1987 DCAST(
ModelNode, node)->set_preserve_transform(ModelNode::PT_local);
1990 case EggGroup::DC_none:
1991 case EggGroup::DC_unspecified:
1995 EggGroup::const_iterator ci;
1996 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1997 make_node(*ci, node);
2005 bool all_polysets =
false;
2006 bool any_hidden =
false;
2011 check_for_polysets(egg_group, all_polysets, any_hidden);
2014 if (all_polysets && !any_hidden) {
2015 node =
new GeomNode(egg_group->get_name());
2017 node =
new PandaNode(egg_group->get_name());
2020 EggGroup::const_iterator ci;
2021 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2022 make_node(*ci, node);
2026 if (node ==
nullptr) {
2032 for (
int gri = 0; gri < num_group_refs; ++gri) {
2034 Groups::const_iterator gi = _groups.find(group_ref);
2035 if (gi != _groups.end()) {
2037 node->add_child(node_ref);
2041 _groups[egg_group] = node;
2042 return create_group_arc(egg_group, parent, node);
2052 parent->add_child(node);
2062 switch (egg_group->get_billboard_type()) {
2063 case EggGroup::BT_point_camera_relative:
2064 node->
set_effect(BillboardEffect::make_point_eye());
2067 case EggGroup::BT_point_world_relative:
2068 node->
set_effect(BillboardEffect::make_point_world());
2071 case EggGroup::BT_axis:
2072 node->
set_effect(BillboardEffect::make_axis());
2075 case EggGroup::BT_none:
2079 if (egg_group->get_decal_flag()) {
2080 if (egg_ignore_decals) {
2082 <<
"Ignoring decal flag on " << egg_group->get_name() <<
"\n";
2089 _decals.insert(node);
2093 EggGroup::TagData::const_iterator ti;
2095 node->
set_tag((*ti).first, (*ti).second);
2098 if (egg_group->get_blend_mode() != EggGroup::BM_unspecified &&
2099 egg_group->get_blend_mode() != EggGroup::BM_none) {
2101 ColorBlendAttrib::Mode mode = get_color_blend_mode(egg_group->get_blend_mode());
2102 ColorBlendAttrib::Operand a = get_color_blend_operand(egg_group->get_blend_operand_a());
2103 ColorBlendAttrib::Operand b = get_color_blend_operand(egg_group->get_blend_operand_b());
2105 node->
set_attrib(ColorBlendAttrib::make(mode, a, b, color));
2112 if (egg_group->has_collide_mask()) {
2113 def._from_collide_mask = egg_group->get_collide_mask();
2114 def._into_collide_mask = egg_group->get_collide_mask();
2116 DeferredNodeProperty::F_has_from_collide_mask |
2117 DeferredNodeProperty::F_has_into_collide_mask;
2119 if (egg_group->has_from_collide_mask()) {
2120 def._from_collide_mask = egg_group->get_from_collide_mask();
2121 def._flags |= DeferredNodeProperty::F_has_from_collide_mask;
2123 if (egg_group->has_into_collide_mask()) {
2124 def._into_collide_mask = egg_group->get_into_collide_mask();
2125 def._flags |= DeferredNodeProperty::F_has_into_collide_mask;
2128 if (def._flags != 0) {
2129 _deferred_nodes[node] = def;
2140 if (egg_table->get_table_type() != EggTable::TT_bundle) {
2143 return make_node(DCAST(
EggGroupNode, egg_table), parent);
2149 parent->add_child(node);
2161 EggGroupNode::const_iterator ci;
2162 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2163 make_node(*ci, node);
2166 parent->add_child(node);
2175 check_for_polysets(
EggGroup *egg_group,
bool &all_polysets,
bool &any_hidden) {
2176 all_polysets = (!egg_group->empty());
2179 EggGroup::const_iterator ci;
2180 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2181 if ((*ci)->is_of_type(EggBin::get_class_type())) {
2183 if (egg_bin->get_bin_number() == EggBinner::BN_polyset) {
2186 EggGroup::const_iterator bci = egg_bin->begin();
2187 nassertv(bci != egg_bin->end());
2189 DCAST_INTO_V(first_prim, (*bci));
2191 DCAST_INTO_V(render_state, first_prim->
get_user_data(EggRenderState::get_class_type()));
2193 if (render_state->_hidden) {
2197 all_polysets =
false;
2200 }
else if ((*ci)->is_of_type(EggGroup::get_class_type())) {
2204 all_polysets =
false;
2220 bool ignore_color) {
2221 VertexPoolTransform vpt;
2222 vpt._vertex_pool = vertex_pool;
2223 vpt._bake_in_uvs = render_state->_bake_in_uvs;
2224 vpt._transform = transform;
2226 VertexPoolData::iterator di;
2227 di = _vertex_pool_data.find(vpt);
2228 if (di != _vertex_pool_data.end()) {
2229 return (*di).second;
2235 Geom::NT_stdfloat, Geom::C_point);
2238 array_format->add_column
2239 (InternalName::get_normal(), 3,
2240 Geom::NT_stdfloat, Geom::C_normal);
2243 if (!ignore_color) {
2247 array_format->add_column(InternalName::get_color(), 1,
2248 Geom::NT_packed_dabc, Geom::C_color);
2250 array_format->add_column(InternalName::get_color(), 4,
2251 Geom::NT_uint8, Geom::C_color);
2255 vector_string uv_names, uvw_names, tbn_names;
2256 vertex_pool->
get_uv_names(uv_names, uvw_names, tbn_names);
2257 vector_string::const_iterator ni;
2258 for (ni = uv_names.begin(); ni != uv_names.end(); ++ni) {
2259 string name = (*ni);
2261 PT(
InternalName) iname = InternalName::get_texcoord_name(name);
2263 if (find(uvw_names.begin(), uvw_names.end(), name) != uvw_names.end()) {
2265 array_format->add_column
2266 (iname, 3, Geom::NT_stdfloat, Geom::C_texcoord);
2268 array_format->add_column
2269 (iname, 2, Geom::NT_stdfloat, Geom::C_texcoord);
2272 for (ni = tbn_names.begin(); ni != tbn_names.end(); ++ni) {
2273 string name = (*ni);
2275 PT(
InternalName) iname_t = InternalName::get_tangent_name(name);
2276 PT(
InternalName) iname_b = InternalName::get_binormal_name(name);
2278 array_format->add_column
2279 (iname_t, 3, Geom::NT_stdfloat, Geom::C_vector);
2280 array_format->add_column
2281 (iname_b, 3, Geom::NT_stdfloat, Geom::C_vector);
2284 vector_string aux_names;
2286 for (ni = aux_names.begin(); ni != aux_names.end(); ++ni) {
2287 string name = (*ni);
2289 array_format->add_column
2290 (iname, 4, Geom::NT_stdfloat, Geom::C_other);
2296 string name = _data->get_egg_filename().get_basename_wo_extension();
2307 temp_format->set_animation(animation);
2311 (InternalName::get_transform_blend(), 1,
2312 Geom::NT_uint16, Geom::C_index, 0, 2);
2313 temp_format->add_array(anim_array_format);
2317 for (vi = vertex_pool->
begin(); vi != vertex_pool->
end(); ++vi) {
2320 EggMorphVertexList::const_iterator mvi;
2321 for (mvi = vertex->_dxyzs.begin(); mvi != vertex->_dxyzs.end(); ++mvi) {
2322 slider_names[(*mvi).get_name()].set_bit(vertex->
get_index());
2323 record_morph(anim_array_format, character_maker, (*mvi).
get_name(),
2324 InternalName::get_vertex(), 3);
2326 if (vertex->has_normal()) {
2327 EggMorphNormalList::const_iterator mni;
2328 for (mni = vertex->_dnormals.begin(); mni != vertex->_dnormals.end(); ++mni) {
2329 slider_names[(*mni).get_name()].set_bit(vertex->
get_index());
2330 record_morph(anim_array_format, character_maker, (*mni).
get_name(),
2331 InternalName::get_normal(), 3);
2334 if (!ignore_color && vertex->has_color()) {
2335 EggMorphColorList::const_iterator mci;
2336 for (mci = vertex->_drgbas.begin(); mci != vertex->_drgbas.end(); ++mci) {
2337 slider_names[(*mci).get_name()].set_bit(vertex->
get_index());
2338 record_morph(anim_array_format, character_maker, (*mci).
get_name(),
2339 InternalName::get_color(), 4);
2345 string name = egg_uv->get_name();
2346 bool has_w = (find(uvw_names.begin(), uvw_names.end(), name) != uvw_names.end());
2347 PT(
InternalName) iname = InternalName::get_texcoord_name(name);
2349 EggMorphTexCoordList::const_iterator mti;
2350 for (mti = egg_uv->_duvs.begin(); mti != egg_uv->_duvs.end(); ++mti) {
2351 slider_names[(*mti).get_name()].set_bit(vertex->
get_index());
2352 record_morph(anim_array_format, character_maker, (*mti).
get_name(),
2353 iname, has_w ? 3 : 2);
2358 if (!slider_names.empty()) {
2364 for (si = slider_names.begin(); si != slider_names.end(); ++si) {
2366 slider_table->add_slider(slider, (*si).second);
2372 name = character_maker->
get_name();
2375 temp_format->maybe_align_columns_for_animation();
2378 GeomVertexFormat::register_format(temp_format);
2386 vertex_data->reserve_num_rows(vertex_pool->
size());
2388 vertex_data->set_transform_blend_table(blend_table);
2389 if (slider_table !=
nullptr) {
2390 vertex_data->set_slider_table(SliderTable::register_table(slider_table));
2395 for (vi = vertex_pool->
begin(); vi != vertex_pool->
end(); ++vi) {
2404 EggMorphVertexList::const_iterator mvi;
2405 for (mvi = vertex->_dxyzs.begin(); mvi != vertex->_dxyzs.end(); ++mvi) {
2408 InternalName::get_morph(InternalName::get_vertex(), morph.get_name());
2410 gvw.
add_data3d(morph.get_offset() * transform);
2414 if (vertex->has_normal()) {
2416 LNormald orig_normal = vertex->get_normal();
2417 LNormald transformed_normal = normalize(orig_normal * transform);
2421 EggMorphNormalList::const_iterator mni;
2422 for (mni = vertex->_dnormals.begin(); mni != vertex->_dnormals.end(); ++mni) {
2425 InternalName::get_morph(InternalName::get_normal(), morph.get_name());
2427 LNormald morphed_normal = orig_normal + morph.get_offset();
2428 LNormald transformed_morphed_normal = normalize(morphed_normal * transform);
2429 LVector3d delta = transformed_morphed_normal - transformed_normal;
2435 if (!ignore_color && vertex->has_color()) {
2440 EggMorphColorList::const_iterator mci;
2441 for (mci = vertex->_drgbas.begin(); mci != vertex->_drgbas.end(); ++mci) {
2444 InternalName::get_morph(InternalName::get_color(), morph.get_name());
2454 LTexCoord3d orig_uvw = egg_uv->
get_uvw();
2455 LTexCoord3d uvw = egg_uv->
get_uvw();
2457 string name = egg_uv->get_name();
2458 PT(
InternalName) iname = InternalName::get_texcoord_name(name);
2461 BakeInUVs::const_iterator buv = render_state->_bake_in_uvs.find(iname);
2462 if (buv != render_state->_bake_in_uvs.end()) {
2464 uvw = uvw * (*buv).second->get_transform3d();
2470 EggMorphTexCoordList::const_iterator mti;
2471 for (mti = egg_uv->_duvs.begin(); mti != egg_uv->_duvs.end(); ++mti) {
2474 InternalName::get_morph(iname, morph.get_name());
2476 LTexCoord3d duvw = morph.get_offset();
2477 if (buv != render_state->_bake_in_uvs.end()) {
2478 LTexCoord3d new_uvw = orig_uvw + duvw;
2479 duvw = (new_uvw * (*buv).second->get_transform3d()) - uvw;
2487 if (egg_uv->has_tangent() && egg_uv->has_binormal()) {
2488 PT(
InternalName) iname = InternalName::get_tangent_name(name);
2491 LVector3d tangent = egg_uv->get_tangent();
2492 LVector3d binormal = egg_uv->get_binormal();
2494 gvw.
set_column(InternalName::get_binormal_name(name));
2503 LVecBase4d aux = egg_aux->
get_aux();
2505 string name = egg_aux->get_name();
2514 gvw.
set_column(InternalName::get_transform_blend());
2519 bool inserted = _vertex_pool_data.insert
2520 (VertexPoolData::value_type(vpt, vertex_data)).second;
2521 nassertr(inserted, vertex_data);
2538 for (vi = vertex_pool->
begin(); vi != vertex_pool->
end(); ++vi) {
2547 nassertr(vt !=
nullptr,
nullptr);
2552 double quantize = egg_vertex_membership_quantize;
2553 EggVertex::GroupRef::const_iterator gri;
2557 if (quantize != 0.0) {
2558 membership = cfloor(membership / quantize + 0.5) * quantize;
2562 nassertr(vt !=
nullptr,
nullptr);
2566 if (egg_vertex_max_num_joints >= 0) {
2571 int table_index = blend_table->add_blend(blend);
2588 int num_components) {
2590 InternalName::get_morph(column_name, morph_name);
2593 (delta_name, num_components,
2594 Geom::NT_stdfloat, Geom::C_morph_delta);
2606 bool has_overall_color,
const LColor &overall_color) {
2608 if (egg_prim->
is_of_type(EggPolygon::get_class_type())) {
2609 if (egg_prim->size() == 3) {
2613 }
else if (egg_prim->
is_of_type(EggTriangleStrip::get_class_type())) {
2616 }
else if (egg_prim->
is_of_type(EggTriangleFan::get_class_type())) {
2619 }
else if (egg_prim->
is_of_type(EggLine::get_class_type())) {
2620 if (egg_prim->size() == 2) {
2621 primitive =
new GeomLines(Geom::UH_static);
2626 }
else if (egg_prim->
is_of_type(EggPoint::get_class_type())) {
2629 }
else if (egg_prim->
is_of_type(EggPatch::get_class_type())) {
2630 int num_vertices = egg_prim->size();
2631 primitive =
new GeomPatches(num_vertices, Geom::UH_static);
2634 if (primitive ==
nullptr) {
2636 egg2pg_cat.warning()
2637 <<
"Ignoring " << egg_prim->get_type() <<
"\n";
2641 if (render_state->_flat_shaded) {
2642 primitive->set_shade_model(GeomPrimitive::SM_flat_first_vertex);
2644 }
else if (egg_prim->
get_shading() == EggPrimitive::S_overall) {
2645 primitive->set_shade_model(GeomPrimitive::SM_uniform);
2648 primitive->set_shade_model(GeomPrimitive::SM_smooth);
2653 PrimitiveUnifier pu(primitive);
2654 std::pair<UniquePrimitives::iterator, bool> result =
2655 unique_primitives.insert(UniquePrimitives::value_type(pu, primitive));
2657 if (result.second) {
2659 primitives.push_back(primitive);
2661 if (egg2pg_cat.is_debug()) {
2663 <<
"First primitive of type " << primitive->get_type()
2664 <<
": " << primitive <<
"\n";
2672 if (orig_prim->
get_num_vertices() + egg_prim->size() <= (
unsigned int)egg_max_indices) {
2673 primitive = orig_prim;
2675 }
else if (orig_prim != primitive) {
2677 (*result.first).second = primitive;
2679 if (egg2pg_cat.is_debug()) {
2681 <<
"Next primitive of type " << primitive->get_type()
2682 <<
": " << primitive <<
"\n";
2684 primitives.push_back(primitive);
2688 EggPrimitive::const_iterator vi;
2689 for (vi = egg_prim->begin(); vi != egg_prim->end(); ++vi) {
2690 primitive->add_vertex((*vi)->get_index());
2692 primitive->close_primitive();
2702 PT(
EggPolygon) poly = find_first_polygon(egg_group);
2703 if (poly !=
nullptr) {
2706 EggPolygon::const_iterator vi;
2707 for (vi = poly->begin(); vi != poly->end(); ++vi) {
2708 LVertexd vert = (*vi)->
get_pos3() * mat;
2719 PT(
EggPolygon) poly = find_first_polygon(egg_group);
2720 if (poly !=
nullptr) {
2721 if (poly->size() != 4) {
2723 <<
"Invalid number of vertices for " << egg_group->get_name() <<
"\n";
2727 LPoint3d v0 = (*poly)[0]->get_pos3() * mat;
2728 LPoint3d v1 = (*poly)[1]->get_pos3() * mat;
2729 LPoint3d v2 = (*poly)[2]->get_pos3() * mat;
2730 LPoint3d v3 = (*poly)[3]->get_pos3() * mat;
2732 LCAST(PN_stdfloat, v1),
2733 LCAST(PN_stdfloat, v2),
2734 LCAST(PN_stdfloat, v3));
2747 find_first_polygon(
EggGroup *egg_group) {
2749 EggGroup::const_iterator ci;
2750 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2751 if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
2758 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2759 if ((*ci)->is_of_type(EggGroup::get_class_type())) {
2761 PT(
EggPolygon) found = find_first_polygon(child_group);
2762 if (found !=
nullptr) {
2778 make_sphere(
EggGroup *egg_group, EggGroup::CollideFlags flags,
2779 LPoint3 ¢er, PN_stdfloat &radius, LColor &color) {
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);
2797 int num_vertices = 0;
2798 LPoint3d d_center(0.0, 0.0, 0.0);
2801 for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
2807 if (num_vertices > 0) {
2808 d_center /= (double)num_vertices;
2812 double radius2 = 0.0;
2813 for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
2816 LVector3d v = p3 - d_center;
2817 radius2 = max(radius2, v.length_squared());
2820 center = LCAST(PN_stdfloat, d_center);
2821 radius = sqrtf(radius2);
2824 vi = vertices.begin();
2838 make_box(
EggGroup *egg_group, EggGroup::CollideFlags flags,
2839 const LMatrix4 &xform, LPoint3 &min_p, LPoint3 &max_p) {
2840 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
2841 if (geom_group !=
nullptr) {
2845 EggGroup::const_iterator ci;
2846 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
2847 if ((*ci)->is_of_type(EggPrimitive::get_class_type())) {
2849 EggPrimitive::const_iterator pi;
2850 for (pi = prim->begin(); pi != prim->end(); ++pi) {
2851 vertices.insert(*pi);
2858 vi = vertices.begin();
2860 if (vi == vertices.end()) {
2868 LPoint3 min_pd = LCAST(PN_stdfloat, vertex->
get_pos3()) * xform;
2869 LPoint3 max_pd = min_pd;
2871 for (++vi; vi != vertices.end(); ++vi) {
2873 LPoint3 pos = LCAST(PN_stdfloat, vertex->
get_pos3()) * xform;
2874 min_pd.set(min(min_pd[0], pos[0]),
2875 min(min_pd[1], pos[1]),
2876 min(min_pd[2], pos[2]));
2877 max_pd.set(max(max_pd[0], pos[0]),
2878 max(max_pd[1], pos[1]),
2879 max(max_pd[2], pos[2]));
2884 return (min_pd != max_pd);
2894 make_box(
EggGroup *egg_group, EggGroup::CollideFlags flags,
2895 LPoint3 &min_p, LPoint3 &max_p, LColor &color) {
2897 color.set(1.0, 1.0, 1.0, 1.0);
2898 return make_box(egg_group, flags, LMatrix4::ident_mat(), min_p, max_p);
2908 if (egg_group->get_cs_type() != EggGroup::CST_none) {
2909 start_group = egg_group;
2912 switch (start_group->get_cs_type()) {
2913 case EggGroup::CST_none:
2917 case EggGroup::CST_plane:
2918 make_collision_plane(egg_group, cnode, start_group->get_collide_flags());
2921 case EggGroup::CST_polygon:
2922 make_collision_polygon(egg_group, cnode, start_group->get_collide_flags());
2925 case EggGroup::CST_polyset:
2926 make_collision_polyset(egg_group, cnode, start_group->get_collide_flags());
2929 case EggGroup::CST_sphere:
2930 make_collision_sphere(egg_group, cnode, start_group->get_collide_flags());
2933 case EggGroup::CST_box:
2934 make_collision_box(egg_group, cnode, start_group->get_collide_flags());
2937 case EggGroup::CST_inv_sphere:
2938 make_collision_inv_sphere(egg_group, cnode, start_group->get_collide_flags());
2941 case EggGroup::CST_tube:
2942 make_collision_capsule(egg_group, cnode, start_group->get_collide_flags());
2945 case EggGroup::CST_floor_mesh:
2946 make_collision_floor_mesh(egg_group, cnode, start_group->get_collide_flags());
2950 if ((start_group->get_collide_flags() & EggGroup::CF_descend) != 0) {
2952 EggGroup::const_iterator ci;
2953 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2954 if ((*ci)->is_of_type(EggGroup::get_class_type())) {
2955 make_collision_solids(start_group, DCAST(
EggGroup, *ci), cnode);
2959 egg2pg_cat.warning()
2960 <<
"Using <Collide> without 'descend' is deprecated. 'descend' "
2961 <<
"will become the default in a future version of Panda3D.\n";
2971 EggGroup::CollideFlags flags) {
2972 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
2973 if (geom_group !=
nullptr) {
2974 EggGroup::const_iterator ci;
2975 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
2976 if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
2978 create_collision_plane(DCAST(
EggPolygon, *ci), egg_group);
2979 if (csplane !=
nullptr) {
2980 apply_collision_flags(csplane, flags);
2981 csplane->
xform(cnode->get_transform()->get_mat());
2985 }
else if ((*ci)->is_of_type(EggCompositePrimitive::get_class_type())) {
2989 make_collision_plane(temp_group, cnode, flags);
3005 EggGroup::CollideFlags flags) {
3007 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
3010 if (geom_group !=
nullptr) {
3011 create_collision_floor_mesh(cnode, geom_group,flags);
3021 EggGroup::CollideFlags flags) {
3023 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
3024 if (geom_group !=
nullptr) {
3025 EggGroup::const_iterator ci;
3026 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
3027 if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
3028 create_collision_polygons(cnode, DCAST(
EggPolygon, *ci),
3030 }
else if ((*ci)->is_of_type(EggCompositePrimitive::get_class_type())) {
3034 make_collision_polygon(temp_group, cnode, flags);
3049 EggGroup::CollideFlags flags) {
3050 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
3051 if (geom_group !=
nullptr) {
3052 EggGroup::const_iterator ci;
3053 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
3054 if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
3055 create_collision_polygons(cnode, DCAST(
EggPolygon, *ci),
3057 }
else if ((*ci)->is_of_type(EggCompositePrimitive::get_class_type())) {
3061 make_collision_polyset(temp_group, cnode, flags);
3074 EggGroup::CollideFlags flags) {
3078 if (make_sphere(egg_group, flags, center, radius, dummycolor)) {
3081 apply_collision_flags(cssphere, flags);
3082 cssphere->xform(cnode->get_transform()->get_mat());
3093 EggGroup::CollideFlags flags) {
3097 if (make_box(egg_group, flags, transform->get_mat(), min_p, max_p)) {
3100 apply_collision_flags(csbox, flags);
3111 EggGroup::CollideFlags flags) {
3115 if (make_sphere(egg_group, flags, center, radius, dummycolor)) {
3118 apply_collision_flags(cssphere, flags);
3119 cssphere->xform(cnode->get_transform()->get_mat());
3130 EggGroup::CollideFlags flags) {
3131 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
3132 if (geom_group !=
nullptr) {
3136 EggGroup::const_iterator ci;
3137 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
3138 if ((*ci)->is_of_type(EggPrimitive::get_class_type())) {
3140 EggPrimitive::const_iterator pi;
3141 for (pi = prim->begin(); pi != prim->end(); ++pi) {
3142 vertices.insert(*pi);
3149 size_t num_vertices = vertices.size();
3150 if (num_vertices != 0) {
3152 vpos.reserve(num_vertices);
3154 LPoint3d center(0.0, 0.0, 0.0);
3156 for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
3158 const LPoint3d &pos = vtx->
get_pos3();
3159 vpos.push_back(pos);
3162 center /= (double)num_vertices;
3168 double radius2 = 0.0;
3169 LPoint3d far_a = center;
3170 for (i = 0; i < num_vertices; i++) {
3171 double dist2 = (vpos[i] - center).length_squared();
3172 if (dist2 > radius2) {
3182 LPoint3d far_b = center;
3183 for (i = 0; i < num_vertices; i++) {
3184 double dist2 = (vpos[i] - far_a).length_squared();
3185 if (dist2 > radius2) {
3202 LPoint3d cap_a_center(0.0, 0.0, 0.0);
3203 LPoint3d cap_b_center(0.0, 0.0, 0.0);
3209 double center_length = (far_a - far_b).length() / 4.0;
3210 double center_length2 = center_length * center_length;
3212 for (i = 0; i < num_vertices; i++) {
3213 double dist2 = (vpos[i] - center).length_squared();
3214 if (dist2 > center_length2) {
3217 double dist_a2 = (vpos[i] - far_a).length_squared();
3218 double dist_b2 = (vpos[i] - far_b).length_squared();
3219 if (dist_a2 < dist_b2) {
3221 cap_a_center += vpos[i];
3225 cap_b_center += vpos[i];
3231 if (num_a > 0 && num_b > 0) {
3232 cap_a_center /= (double)num_a;
3233 cap_b_center /= (double)num_b;
3237 LVector3d axis = cap_b_center - cap_a_center;
3242 if (IS_THRESHOLD_ZERO(axis[0], 0.01)) {
3245 if (IS_THRESHOLD_ZERO(axis[1], 0.01)) {
3248 if (IS_THRESHOLD_ZERO(axis[2], 0.01)) {
3260 look_at(mat, axis, LVector3d(0.0, 0.0, 1.0), CS_zup_right);
3261 mat.set_row(3, center);
3263 inv_mat.invert_from(mat);
3265 for (i = 0; i < num_vertices; i++) {
3266 vpos[i] = vpos[i] * inv_mat;
3269 double max_radius2 = 0.0;
3272 for (i = 0; i < num_vertices; i++) {
3273 LVector2d v(vpos[i][0], vpos[i][2]);
3274 double radius2 = v.length_squared();
3275 if (radius2 > max_radius2) {
3276 max_radius2 = radius2;
3286 for (i = 0; i < num_vertices; i++) {
3287 LVector2d v(vpos[i][0], vpos[i][2]);
3288 double radius2 = v.length_squared();
3290 if (vpos[i][1] < min_y) {
3293 double factor = sqrt(max_radius2 - radius2);
3294 min_y = min(min_y, vpos[i][1] + factor);
3296 }
else if (vpos[i][1] > max_y) {
3297 double factor = sqrt(max_radius2 - radius2);
3298 max_y = max(max_y, vpos[i][1] - factor);
3302 double length = max_y - min_y;
3303 double radius = sqrt(max_radius2);
3306 LVector3d half = axis * (length / 2.0);
3307 LPoint3d point_a = center - half;
3308 LPoint3d point_b = center + half;
3311 new CollisionCapsule(LCAST(PN_stdfloat, point_a), LCAST(PN_stdfloat, point_b),
3313 apply_collision_flags(cscapsule, flags);
3314 cscapsule->xform(cnode->get_transform()->get_mat());
3326 apply_collision_flags(
CollisionSolid *solid, EggGroup::CollideFlags flags) {
3327 if ((flags & EggGroup::CF_intangible) != 0) {
3330 if ((flags & EggGroup::CF_level) != 0) {
3340 find_collision_geometry(
EggGroup *egg_group, EggGroup::CollideFlags flags) {
3341 if ((flags & EggGroup::CF_descend) != 0) {
3348 EggGroup::const_iterator ci;
3349 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
3350 if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
3358 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
3359 if ((*ci)->is_of_type(EggGroup::get_class_type())) {
3361 if (child_group->get_cs_type() == egg_group->get_cs_type()) {
3378 <<
"Ignoring degenerate collision plane in " << parent_group->get_name()
3384 egg2pg_cat.warning()
3385 <<
"Non-planar polygon defining collision plane in "
3386 << parent_group->get_name()
3391 if (!egg_poly->empty()) {
3392 EggPolygon::const_iterator vi;
3393 vi = egg_poly->begin();
3395 LVertexd vert = (*vi)->get_pos3();
3396 vertices.push_back(LCAST(PN_stdfloat, vert));
3398 LVertexd last_vert = vert;
3400 while (vi != egg_poly->end()) {
3401 vert = (*vi)->get_pos3();
3402 if (!vert.almost_equal(last_vert)) {
3403 vertices.push_back(LCAST(PN_stdfloat, vert));
3411 if (vertices.size() < 3) {
3414 LPlane plane(vertices[0], vertices[1], vertices[2]);
3425 EggGroup::CollideFlags flags) {
3431 <<
"Ignoring degenerate collision polygon in "
3432 << parent_group->get_name()
3437 if (group->size() != 1) {
3439 <<
"Triangulating concave or non-planar collision polygon in "
3440 << parent_group->get_name()
3444 EggGroup::iterator ci;
3445 for (ci = group->begin(); ci != group->end(); ++ci) {
3449 if (!poly->empty()) {
3450 EggPolygon::const_iterator vi;
3453 LVertexd vert = (*vi)->get_pos3();
3454 vertices.push_back(LCAST(PN_stdfloat, vert));
3456 LVertexd last_vert = vert;
3458 while (vi != poly->end()) {
3459 vert = (*vi)->get_pos3();
3460 if (!vert.almost_equal(last_vert)) {
3461 vertices.push_back(LCAST(PN_stdfloat, vert));
3469 if (vertices.size() >= 3) {
3470 const LVertex *vertices_begin = &vertices[0];
3471 const LVertex *vertices_end = vertices_begin + vertices.size();
3474 if (cspoly->is_valid()) {
3475 apply_collision_flags(cspoly, flags);
3476 cspoly->xform(cnode->get_transform()->get_mat());
3490 EggGroup::CollideFlags flags) {
3494 pool.local_object();
3495 EggGroup::const_iterator egi;
3496 for (egi = parent_group->begin(); egi != parent_group->end(); ++egi) {
3497 if ((*egi)->is_of_type(EggPolygon::get_class_type())) {
3501 <<
"Ignoring degenerate collision polygon in "
3502 << parent_group->get_name()
3509 if(group->size() == 0) {
3511 <<
"empty collision solid\n";
3517 EggGroup::iterator ci;
3518 for (ci = group->begin(); ci != group->end(); ++ci) {
3520 if (poly->get_num_vertices() == 3) {
3521 CollisionFloorMesh::TriangleIndices tri;
3524 tri.p1=pool.create_unique_vertex(*poly->
get_vertex(0))->get_index();
3525 tri.p2=pool.create_unique_vertex(*poly->
get_vertex(1))->get_index();
3526 tri.p3=pool.create_unique_vertex(*poly->
get_vertex(2))->get_index();
3528 triangles.push_back(tri);
3529 }
else if (poly->get_num_vertices() == 4) {
3532 CollisionFloorMesh::TriangleIndices tri;
3533 CollisionFloorMesh::TriangleIndices tri2;
3536 tri.p1=pool.create_unique_vertex(*poly->
get_vertex(0))->get_index();
3537 tri.p2=pool.create_unique_vertex(*poly->
get_vertex(1))->get_index();
3538 tri.p3=pool.create_unique_vertex(*poly->
get_vertex(2))->get_index();
3540 triangles.push_back(tri);
3545 tri2.p3=pool.create_unique_vertex(*poly->
get_vertex(3))->get_index();
3548 triangles.push_back(tri2);
3557 for (vi = pool.begin(); vi != pool.end(); vi++) {
3558 csfloor->add_vertex(LCAST(PN_stdfloat,(*vi)->get_pos3()));
3563 for (ti = triangles.begin(); ti != triangles.end(); ti++) {
3564 CollisionFloorMesh::TriangleIndices triangle = *ti;
3565 csfloor->add_triangle(triangle.p1, triangle.p2, triangle.p3);
3567 csfloor->xform(cnode->get_transform()->get_mat());
3581 DeferredNodes::const_iterator dni;
3582 dni = _deferred_nodes.find(node);
3584 if (dni != _deferred_nodes.end()) {
3590 next_prop.apply_to_node(node);
3593 for (
int i = 0; i < num_children; i++) {
3594 apply_deferred_nodes(node->
get_child(i), next_prop);
3607 expand_all_object_types(
EggNode *egg_node) {
3608 if (egg_node->
is_of_type(EggGroup::get_class_type())) {
3611 if (egg_group->get_num_object_types() != 0) {
3614 if (!expand_object_types(egg_group, expanded, expanded_history)) {
3622 if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
3624 EggGroupNode::const_iterator ci;
3625 ci = egg_group_node->begin();
3626 while (ci != egg_group_node->end()) {
3627 EggGroupNode::const_iterator cnext = ci;
3630 if (!expand_all_object_types(*ci)) {
3632 egg_group_node->erase(ci);
3653 int num_object_types = egg_group->get_num_object_types();
3656 vector_string object_types;
3658 for (i = 0; i < num_object_types; i++) {
3659 object_types.push_back(egg_group->get_object_type(i));
3661 egg_group->clear_object_types();
3663 for (i = 0; i < num_object_types; i++) {
3664 string object_type = object_types[i];
3668 if (!new_expanded.insert(object_type).second) {
3670 <<
"Cycle in ObjectType expansions:\n";
3672 for (pi = expanded_history.begin();
3673 pi != expanded_history.end();
3675 egg2pg_cat.error(
false)
3678 egg2pg_cat.error(
false) << object_type <<
"\n";
3684 new_expanded_history.push_back(object_type);
3686 if (!do_expand_object_type(egg_group, new_expanded,
3687 new_expanded_history, object_type)) {
3703 const string &object_type) {
3708 (
"egg-object-type-" +
downcase(object_type),
"");
3709 string egg_syntax = egg_object_type;
3711 if (!egg_object_type.has_value()) {
3714 if (cmp_nocase_uh(object_type,
"barrier") == 0) {
3715 egg_syntax =
"<Collide> { Polyset descend }";
3717 }
else if (cmp_nocase_uh(object_type,
"solidpoly") == 0) {
3718 egg_syntax =
"<Collide> { Polyset descend solid }";
3720 }
else if (cmp_nocase_uh(object_type,
"turnstile") == 0) {
3721 egg_syntax =
"<Collide> { Polyset descend turnstile }";
3723 }
else if (cmp_nocase_uh(object_type,
"sphere") == 0) {
3724 egg_syntax =
"<Collide> { Sphere descend }";
3726 }
else if (cmp_nocase_uh(object_type,
"tube") == 0) {
3727 egg_syntax =
"<Collide> { Tube descend }";
3729 }
else if (cmp_nocase_uh(object_type,
"trigger") == 0) {
3730 egg_syntax =
"<Collide> { Polyset descend intangible }";
3732 }
else if (cmp_nocase_uh(object_type,
"trigger_sphere") == 0) {
3733 egg_syntax =
"<Collide> { Sphere descend intangible }";
3735 }
else if (cmp_nocase_uh(object_type,
"eye_trigger") == 0) {
3736 egg_syntax =
"<Collide> { Polyset descend intangible center }";
3738 }
else if (cmp_nocase_uh(object_type,
"bubble") == 0) {
3739 egg_syntax =
"<Collide> { Sphere keep descend }";
3741 }
else if (cmp_nocase_uh(object_type,
"ghost") == 0) {
3742 egg_syntax =
"<Scalar> collide-mask { 0 }";
3744 }
else if (cmp_nocase_uh(object_type,
"dcs") == 0) {
3745 egg_syntax =
"<DCS> { 1 }";
3747 }
else if (cmp_nocase_uh(object_type,
"model") == 0) {
3748 egg_syntax =
"<Model> { 1 }";
3750 }
else if (cmp_nocase_uh(object_type,
"none") == 0) {
3754 }
else if (cmp_nocase_uh(object_type,
"backstage") == 0) {
3760 <<
"Unknown ObjectType " << object_type <<
"\n";
3762 egg2pg_cat.debug() <<
"returning true\n";
3767 if (!egg_syntax.empty()) {
3768 if (!egg_group->
parse_egg(egg_syntax)) {
3770 <<
"Error while parsing definition for ObjectType "
3771 << object_type <<
"\n";
3777 if (egg_group->get_num_object_types() != 0) {
3778 if (!expand_object_types(egg_group, expanded, expanded_history)) {
3792 TextureStage::CombineMode EggLoader::
3794 EggTexture::CombineChannel channel) {
3795 switch (egg_tex->get_combine_mode(channel)) {
3796 case EggTexture::CM_unspecified:
3799 case EggTexture::CM_modulate:
3800 return TextureStage::CM_modulate;
3802 case EggTexture::CM_replace:
3803 return TextureStage::CM_replace;
3805 case EggTexture::CM_add:
3806 return TextureStage::CM_add;
3808 case EggTexture::CM_add_signed:
3809 return TextureStage::CM_add_signed;
3811 case EggTexture::CM_interpolate:
3812 return TextureStage::CM_interpolate;
3814 case EggTexture::CM_subtract:
3815 return TextureStage::CM_subtract;
3817 case EggTexture::CM_dot3_rgb:
3818 return TextureStage::CM_dot3_rgb;
3820 case EggTexture::CM_dot3_rgba:
3821 return TextureStage::CM_dot3_rgba;
3824 return TextureStage::CM_undefined;
3831 TextureStage::CombineSource EggLoader::
3832 get_combine_source(
const EggTexture *egg_tex,
3833 EggTexture::CombineChannel channel,
int n) {
3834 switch (egg_tex->get_combine_source(channel, n)) {
3835 case EggTexture::CS_unspecified:
3840 return TextureStage::CS_previous;
3842 return TextureStage::CS_texture;
3844 return TextureStage::CS_constant;
3848 case EggTexture::CS_texture:
3849 return TextureStage::CS_texture;
3851 case EggTexture::CS_constant:
3852 return TextureStage::CS_constant;
3854 case EggTexture::CS_primary_color:
3855 return TextureStage::CS_primary_color;
3857 case EggTexture::CS_previous:
3858 return TextureStage::CS_previous;
3860 case EggTexture::CS_constant_color_scale:
3861 return TextureStage::CS_constant_color_scale;
3863 case EggTexture::CS_last_saved_result:
3864 return TextureStage::CS_last_saved_result;
3867 return TextureStage::CS_undefined;
3874 TextureStage::CombineOperand EggLoader::
3875 get_combine_operand(
const EggTexture *egg_tex,
3876 EggTexture::CombineChannel channel,
int n) {
3877 switch (egg_tex->get_combine_operand(channel, n)) {
3878 case EggTexture::CO_unspecified:
3879 if (channel == EggTexture::CC_rgb) {
3882 return n < 2 ? TextureStage::CO_src_color : TextureStage::CO_src_alpha;
3885 return TextureStage::CO_src_alpha;
3888 case EggTexture::CO_src_color:
3889 return TextureStage::CO_src_color;
3891 case EggTexture::CO_one_minus_src_color:
3892 return TextureStage::CO_one_minus_src_color;
3894 case EggTexture::CO_src_alpha:
3895 return TextureStage::CO_src_alpha;
3897 case EggTexture::CO_one_minus_src_alpha:
3898 return TextureStage::CO_one_minus_src_alpha;
3901 return TextureStage::CO_undefined;
3908 ColorBlendAttrib::Mode EggLoader::
3909 get_color_blend_mode(EggGroup::BlendMode mode) {
3911 case EggGroup::BM_unspecified:
3912 case EggGroup::BM_none:
3913 return ColorBlendAttrib::M_none;
3914 case EggGroup::BM_add:
3915 return ColorBlendAttrib::M_add;
3916 case EggGroup::BM_subtract:
3917 return ColorBlendAttrib::M_subtract;
3918 case EggGroup::BM_inv_subtract:
3919 return ColorBlendAttrib::M_inv_subtract;
3920 case EggGroup::BM_min:
3921 return ColorBlendAttrib::M_min;
3922 case EggGroup::BM_max:
3923 return ColorBlendAttrib::M_max;
3926 return ColorBlendAttrib::M_none;
3933 ColorBlendAttrib::Operand EggLoader::
3934 get_color_blend_operand(EggGroup::BlendOperand operand) {
3936 case EggGroup::BO_zero:
3937 return ColorBlendAttrib::O_zero;
3938 case EggGroup::BO_unspecified:
3939 case EggGroup::BO_one:
3940 return ColorBlendAttrib::O_one;
3941 case EggGroup::BO_incoming_color:
3942 return ColorBlendAttrib::O_incoming_color;
3943 case EggGroup::BO_one_minus_incoming_color:
3944 return ColorBlendAttrib::O_one_minus_incoming_color;
3945 case EggGroup::BO_fbuffer_color:
3946 return ColorBlendAttrib::O_fbuffer_color;
3947 case EggGroup::BO_one_minus_fbuffer_color:
3948 return ColorBlendAttrib::O_one_minus_fbuffer_color;
3949 case EggGroup::BO_incoming_alpha:
3950 return ColorBlendAttrib::O_incoming_alpha;
3951 case EggGroup::BO_one_minus_incoming_alpha:
3952 return ColorBlendAttrib::O_one_minus_incoming_alpha;
3953 case EggGroup::BO_fbuffer_alpha:
3954 return ColorBlendAttrib::O_fbuffer_alpha;
3955 case EggGroup::BO_one_minus_fbuffer_alpha:
3956 return ColorBlendAttrib::O_one_minus_fbuffer_alpha;
3957 case EggGroup::BO_constant_color:
3958 return ColorBlendAttrib::O_constant_color;
3959 case EggGroup::BO_one_minus_constant_color:
3960 return ColorBlendAttrib::O_one_minus_constant_color;
3961 case EggGroup::BO_constant_alpha:
3962 return ColorBlendAttrib::O_constant_alpha;
3963 case EggGroup::BO_one_minus_constant_alpha:
3964 return ColorBlendAttrib::O_one_minus_constant_alpha;
3965 case EggGroup::BO_incoming_color_saturate:
3966 return ColorBlendAttrib::O_incoming_color_saturate;
3967 case EggGroup::BO_color_scale:
3968 return ColorBlendAttrib::O_color_scale;
3969 case EggGroup::BO_one_minus_color_scale:
3970 return ColorBlendAttrib::O_one_minus_color_scale;
3971 case EggGroup::BO_alpha_scale:
3972 return ColorBlendAttrib::O_alpha_scale;
3973 case EggGroup::BO_one_minus_alpha_scale:
3974 return ColorBlendAttrib::O_one_minus_alpha_scale;
3977 return ColorBlendAttrib::O_zero;
3983 bool EggLoader::VertexPoolTransform::
3984 operator < (
const EggLoader::VertexPoolTransform &other)
const {
3985 if (_vertex_pool != other._vertex_pool) {
3986 return _vertex_pool < other._vertex_pool;
3988 int compare = _transform.compare_to(other._transform, 0.001);
3993 if (_bake_in_uvs.size() != other._bake_in_uvs.size()) {
3994 return _bake_in_uvs.size() < other._bake_in_uvs.size();
3997 BakeInUVs::const_iterator ai, bi;
3998 ai = _bake_in_uvs.begin();
3999 bi = other._bake_in_uvs.begin();
4000 while (ai != _bake_in_uvs.end()) {
4001 nassertr(bi != other._bake_in_uvs.end(),
false);
4002 if ((*ai) != (*bi)) {
4003 return (*ai) < (*bi);
4008 nassertr(bi == other._bake_in_uvs.end(),
false);