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