15 #include "pandabase.h" 17 #include "eggLoader.h" 18 #include "eggRenderState.h" 19 #include "egg_parametrics.h" 20 #include "config_egg2pg.h" 21 #include "config_egg.h" 23 #include "renderState.h" 24 #include "transformState.h" 25 #include "texturePool.h" 26 #include "billboardEffect.h" 27 #include "decalEffect.h" 28 #include "colorAttrib.h" 29 #include "textureAttrib.h" 30 #include "materialPool.h" 32 #include "geomVertexFormat.h" 33 #include "geomVertexArrayFormat.h" 34 #include "geomVertexData.h" 35 #include "geomVertexWriter.h" 37 #include "geomTriangles.h" 38 #include "geomTristrips.h" 39 #include "geomTrifans.h" 40 #include "geomLines.h" 41 #include "geomLinestrips.h" 42 #include "geomPoints.h" 43 #include "geomPatches.h" 44 #include "sequenceNode.h" 45 #include "switchNode.h" 46 #include "portalNode.h" 47 #include "occluderNode.h" 48 #include "polylightNode.h" 50 #include "modelNode.h" 51 #include "modelRoot.h" 52 #include "string_utils.h" 53 #include "eggPrimitive.h" 57 #include "eggTextureCollection.h" 58 #include "eggNurbsCurve.h" 59 #include "eggNurbsSurface.h" 60 #include "eggGroupNode.h" 62 #include "eggPolygon.h" 63 #include "eggTriangleStrip.h" 64 #include "eggTriangleFan.h" 67 #include "eggBinner.h" 68 #include "eggVertexPool.h" 69 #include "pt_EggTexture.h" 70 #include "characterMaker.h" 71 #include "character.h" 72 #include "animBundleMaker.h" 73 #include "animBundleNode.h" 74 #include "selectiveChildNode.h" 75 #include "collisionNode.h" 76 #include "collisionSphere.h" 77 #include "collisionInvSphere.h" 78 #include "collisionTube.h" 79 #include "collisionPlane.h" 80 #include "collisionPolygon.h" 81 #include "collisionFloorMesh.h" 82 #include "collisionBox.h" 83 #include "parametricCurve.h" 84 #include "nurbsCurve.h" 85 #include "nurbsCurveInterface.h" 86 #include "nurbsCurveEvaluator.h" 87 #include "nurbsSurfaceEvaluator.h" 89 #include "sheetNode.h" 91 #include "configVariableString.h" 92 #include "transformBlendTable.h" 93 #include "transformBlend.h" 94 #include "sparseArray.h" 97 #include "uvScrollNode.h" 98 #include "textureStagePool.h" 110 return _d->_switch_in < other._d->_switch_in;
118 LODInstance(
EggNode *egg_node) {
119 nassertv(egg_node != NULL);
120 _egg_node = egg_node;
126 nassertv(egg_group->has_lod());
145 _dynamic_override =
false;
146 _dynamic_override_char_maker = NULL;
160 _dynamic_override =
false;
161 _dynamic_override_char_maker = NULL;
172 _deferred_nodes.clear();
176 if (!expand_all_object_types(_data)) {
184 _data->clear_connected_shading();
185 _data->remove_unused_vertices(
true);
186 _data->get_connected_shading();
187 _data->unify_attributes(
true, egg_flat_shading,
true);
193 _data->clear_connected_shading();
194 _data->remove_unused_vertices(
true);
195 _data->get_connected_shading();
201 separate_switches(_data);
203 if (egg_emulate_bface) {
204 emulate_bface(_data);
208 _data->remove_invalid_primitives(
true);
215 _root =
new ModelRoot(_data->get_egg_filename(), _data->get_egg_timestamp());
217 EggGroupNode::const_iterator ci;
218 for (ci = _data->begin(); ci != _data->end(); ++ci) {
219 make_node(*ci, _root);
238 ExtraNodes::const_iterator di;
239 for (di = _decals.begin(); di != _decals.end(); ++di) {
249 for (
int i = 0; i < num_children; i++) {
256 <<
"Decal onto " << parent.
node()->get_name()
257 <<
" uses base geometry with multiple GeomNodes.\n";
267 <<
"Ignoring decal onto " << parent.
node()->get_name()
268 <<
"; no geometry within group.\n";
275 while (i < num_children) {
303 ExtraNodes::const_iterator ni;
304 for (ni = _sequences.begin(); ni != _sequences.end(); ++ni) {
323 if (egg_bin->empty()) {
331 EggGroupNode::const_iterator ci = egg_bin->begin();
332 nassertv(ci != egg_bin->end());
336 DCAST_INTO_V(render_state, first_prim->get_user_data(EggRenderState::get_class_type()));
338 if (render_state->_hidden && egg_suppress_hidden) {
353 egg_bin->
mesh_triangles(render_state->_flat_shaded ? EggGroupNode::T_flat_shaded : 0);
374 EggVertexPools::iterator vpi;
375 for (vpi = vertex_pools.begin(); vpi != vertex_pools.end(); ++vpi) {
380 bool has_overall_color;
383 if (!egg_flat_colors) {
387 has_overall_color =
false;
394 blend_table = make_blend_table(vertex_pool, egg_bin, character_maker);
408 for (ci = egg_bin->begin(); ci != egg_bin->end(); ++ci) {
410 DCAST_INTO_V(egg_prim, (*ci));
411 if (egg_prim->
get_pool() == vertex_pool) {
412 make_primitive(render_state, egg_prim, unique_primitives, primitives,
413 has_overall_color, overall_color);
417 if (!primitives.empty()) {
419 if (transform != NULL) {
427 make_vertex_data(render_state, vertex_pool, egg_bin, mat, blend_table,
428 is_dynamic, character_maker, has_overall_color);
432 PT(
Geom) geom =
new Geom(vertex_data);
435 Primitives::const_iterator pi;
436 for (pi = primitives.begin(); pi != primitives.end(); ++pi) {
439 if (primitive->is_indexed()) {
442 primitive->reserve_num_vertices(primitive->get_num_vertices());
445 geom->add_primitive(primitive);
453 if (geom_node == (
GeomNode *)NULL) {
458 geom_node = DCAST(
GeomNode, parent);
461 geom_node =
new GeomNode(egg_bin->get_name());
462 if (render_state->_hidden) {
465 parent->add_child(geom_node);
470 CPT(
RenderState) geom_state = render_state->_state;
471 if (has_overall_color) {
473 geom_state = geom_state->
add_attrib(ColorAttrib::make_flat(overall_color), -1);
476 geom_state = geom_state->add_attrib(ColorAttrib::make_vertex(), -1);
479 geom_node->
add_geom(geom, geom_state);
483 if (geom_node != (
GeomNode *)NULL && egg_show_normals) {
485 for (vpi = vertex_pools.begin(); vpi != vertex_pools.end(); ++vpi) {
487 show_normals(vertex_pool, geom_node);
498 CPT(TransformState) EggLoader::
503 CPT(TransformState) ts = TransformState::make_identity();
505 for (
int i = 0; i < num_components; i++) {
507 case EggTransform::CT_translate2d:
510 LVecBase3 trans3d(trans2d[0], trans2d[1], 0.0f);
511 ts = TransformState::make_pos(trans3d)->compose(ts);
515 case EggTransform::CT_translate3d:
518 ts = TransformState::make_pos(trans3d)->compose(ts);
522 case EggTransform::CT_rotate2d:
526 ts = TransformState::make_quat(rot)->compose(ts);
530 case EggTransform::CT_rotx:
534 ts = TransformState::make_quat(rot)->compose(ts);
538 case EggTransform::CT_roty:
542 ts = TransformState::make_quat(rot)->compose(ts);
546 case EggTransform::CT_rotz:
550 ts = TransformState::make_quat(rot)->compose(ts);
554 case EggTransform::CT_rotate3d:
558 ts = TransformState::make_quat(rot)->compose(ts);
562 case EggTransform::CT_scale2d:
565 LVecBase3 scale3d(scale2d[0], scale2d[1], 1.0f);
566 ts = TransformState::make_scale(scale3d)->compose(ts);
570 case EggTransform::CT_scale3d:
573 ts = TransformState::make_scale(scale3d)->compose(ts);
577 case EggTransform::CT_uniform_scale:
580 ts = TransformState::make_scale(scale)->compose(ts);
584 case EggTransform::CT_matrix3:
587 LMatrix4 mat4(m(0, 0), m(0, 1), 0.0, m(0, 2),
588 m(1, 0), m(1, 1), 0.0, m(1, 2),
590 m(2, 0), m(2, 1), 0.0, m(2, 2));
592 ts = TransformState::make_mat(mat4)->compose(ts);
596 case EggTransform::CT_matrix4:
599 ts = TransformState::make_mat(mat4)->compose(ts);
603 case EggTransform::CT_invalid:
609 if (ts->components_given()) {
619 TransformStates::iterator tsi = _transform_states.insert(TransformStates::value_type(ts->get_mat(), ts)).first;
621 return (*tsi).second;
634 CPT(GeomVertexFormat) format = GeomVertexFormat::get_v3cp();
636 new GeomVertexData(vertex_pool->get_name(), format, Geom::UH_static);
642 for (vi = vertex_pool->
begin(); vi != vertex_pool->
end(); ++vi) {
646 if (vert->has_normal()) {
647 vertex.add_data3d(pos);
648 vertex.add_data3d(pos + vert->get_normal() * egg_normal_scale);
651 primitive->add_next_vertices(2);
652 primitive->close_primitive();
660 if (uv_obj->has_tangent()) {
661 vertex.add_data3d(pos);
662 vertex.add_data3d(pos + uv_obj->get_tangent() * egg_normal_scale);
665 primitive->add_next_vertices(2);
666 primitive->close_primitive();
668 if (uv_obj->has_binormal()) {
669 vertex.add_data3d(pos);
670 vertex.add_data3d(pos + uv_obj->get_binormal() * egg_normal_scale);
673 primitive->add_next_vertices(2);
674 primitive->close_primitive();
679 PT(
Geom) geom =
new Geom(vertex_data);
680 geom->add_primitive(primitive);
692 if (egg_load_old_curves) {
694 make_old_nurbs_curve(egg_curve, parent, mat);
698 assert(parent != NULL);
731 int subdiv_per_segment =
732 (int)((egg_curve->
get_subdiv() + 0.5) / nurbs->get_num_segments());
733 rope->set_num_subdiv(max(subdiv_per_segment, 1));
737 DCAST_INTO_V(render_state, egg_curve->
get_user_data(EggRenderState::get_class_type()));
738 if (render_state->_hidden && egg_suppress_hidden) {
743 rope->set_state(render_state->_state);
744 rope->set_uv_mode(RopeNode::UV_parametric);
748 rope->set_use_vertex_color(
true);
749 }
else if (egg_curve->has_color()) {
751 rope->set_attrib(ColorAttrib::make_flat(egg_curve->
get_color()));
754 parent->add_child(rope);
768 assert(parent != NULL);
779 <<
"Invalid NURBSCurve order for " << egg_curve->get_name() <<
": " 785 nurbs->set_order(egg_curve->
get_order());
787 EggPrimitive::const_iterator pi;
788 for (pi = egg_curve->begin(); pi != egg_curve->end(); ++pi) {
789 nurbs->append_cv(LCAST(PN_stdfloat, (*pi)->get_pos4() * mat));
793 if (num_knots != nurbs->get_num_knots()) {
795 <<
"Invalid NURBSCurve number of knots for " 796 << egg_curve->get_name() <<
": got " << num_knots
797 <<
" knots, expected " << nurbs->get_num_knots() <<
"\n";
802 for (
int i = 0; i < num_knots; i++) {
803 nurbs->set_knot(i, egg_curve->
get_knot(i));
807 case EggCurve::CT_xyz:
808 curve->set_curve_type(PCT_XYZ);
811 case EggCurve::CT_hpr:
812 curve->set_curve_type(PCT_HPR);
816 curve->set_curve_type(PCT_T);
822 curve->set_name(egg_curve->get_name());
824 if (!curve->recompute()) {
826 <<
"Invalid NURBSCurve " << egg_curve->get_name() <<
"\n";
831 parent->add_child(curve);
842 assert(parent != NULL);
856 int u_subdiv_per_segment =
857 (int)((egg_surface->
get_u_subdiv() + 0.5) / nurbs->get_num_u_segments());
858 sheet->set_num_u_subdiv(max(u_subdiv_per_segment, 1));
861 int v_subdiv_per_segment =
862 (int)((egg_surface->
get_v_subdiv() + 0.5) / nurbs->get_num_v_segments());
863 sheet->set_num_v_subdiv(max(v_subdiv_per_segment, 1));
867 DCAST_INTO_V(render_state, egg_surface->
get_user_data(EggRenderState::get_class_type()));
868 if (render_state->_hidden && egg_suppress_hidden) {
873 sheet->set_state(render_state->_state);
877 sheet->set_use_vertex_color(
true);
878 }
else if (egg_surface->has_color()) {
880 sheet->set_attrib(ColorAttrib::make_flat(egg_surface->
get_color()));
883 parent->add_child(sheet);
897 EggTextureCollection::iterator ti;
898 for (ti = tc.begin(); ti != tc.end(); ++ti) {
899 PT_EggTexture egg_tex = (*ti);
902 if (load_texture(def, egg_tex)) {
905 _textures[egg_tex] = def;
917 load_texture(TextureDef &def,
EggTexture *egg_tex) {
920 int wanted_channels = 0;
921 bool wanted_alpha =
false;
922 switch (egg_tex->get_format()) {
923 case EggTexture::F_red:
924 case EggTexture::F_green:
925 case EggTexture::F_blue:
926 case EggTexture::F_alpha:
927 case EggTexture::F_luminance:
929 wanted_alpha =
false;
932 case EggTexture::F_luminance_alpha:
933 case EggTexture::F_luminance_alphamask:
938 case EggTexture::F_rgb:
939 case EggTexture::F_rgb12:
940 case EggTexture::F_rgb8:
941 case EggTexture::F_rgb5:
942 case EggTexture::F_rgb332:
944 wanted_alpha =
false;
947 case EggTexture::F_rgba:
948 case EggTexture::F_rgbm:
949 case EggTexture::F_rgba12:
950 case EggTexture::F_rgba8:
951 case EggTexture::F_rgba4:
952 case EggTexture::F_rgba5:
957 case EggTexture::F_unspecified:
974 if (egg_preload_simple_textures) {
975 options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_preload_simple);
978 if (!egg_ignore_filters && !egg_ignore_mipmaps) {
979 switch (egg_tex->get_minfilter()) {
980 case EggTexture::FT_nearest:
981 case EggTexture::FT_linear:
982 case EggTexture::FT_unspecified:
985 case EggTexture::FT_nearest_mipmap_nearest:
986 case EggTexture::FT_linear_mipmap_nearest:
987 case EggTexture::FT_nearest_mipmap_linear:
988 case EggTexture::FT_linear_mipmap_linear:
989 options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_generate_mipmaps);
994 options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_multiview);
1001 switch (egg_tex->get_texture_type()) {
1002 case EggTexture::TT_unspecified:
1003 case EggTexture::TT_1d_texture:
1004 options.set_texture_flags(options.get_texture_flags() | LoaderOptions::TF_allow_1d);
1007 case EggTexture::TT_2d_texture:
1021 case EggTexture::TT_3d_texture:
1026 case EggTexture::TT_cube_map:
1048 aux->
is_of_type(EggTexture::get_class_type())) {
1051 if (aux_egg_tex->
get_alpha_mode() != EggTexture::AM_unspecified) {
1054 if (aux_egg_tex->get_format() != EggTexture::F_unspecified) {
1055 egg_tex->set_format(aux_egg_tex->get_format());
1057 if (aux_egg_tex->get_minfilter() != EggTexture::FT_unspecified) {
1058 egg_tex->set_minfilter(aux_egg_tex->get_minfilter());
1060 if (aux_egg_tex->get_magfilter() != EggTexture::FT_unspecified) {
1061 egg_tex->set_magfilter(aux_egg_tex->get_magfilter());
1068 apply_texture_attributes(tex, egg_tex);
1072 def._texture = DCAST(
TextureAttrib, TextureAttrib::make())->add_on_stage(stage, tex);
1074 def._egg_tex = egg_tex;
1087 if (egg_tex->get_compression_mode() != EggTexture::CM_default) {
1088 tex->
set_compression(convert_compression_mode(egg_tex->get_compression_mode()));
1095 if (wrap_u != EggTexture::WM_unspecified) {
1098 if (wrap_v != EggTexture::WM_unspecified) {
1101 if (wrap_w != EggTexture::WM_unspecified) {
1109 switch (egg_tex->get_minfilter()) {
1110 case EggTexture::FT_nearest:
1114 case EggTexture::FT_linear:
1115 if (egg_ignore_filters) {
1116 egg2pg_cat.warning()
1117 <<
"Ignoring minfilter request\n";
1124 case EggTexture::FT_nearest_mipmap_nearest:
1125 if (egg_ignore_filters) {
1126 egg2pg_cat.warning()
1127 <<
"Ignoring minfilter request\n";
1129 }
else if (egg_ignore_mipmaps) {
1130 egg2pg_cat.warning()
1131 <<
"Ignoring mipmap request\n";
1134 tex->
set_minfilter(SamplerState::FT_nearest_mipmap_nearest);
1138 case EggTexture::FT_linear_mipmap_nearest:
1139 if (egg_ignore_filters) {
1140 egg2pg_cat.warning()
1141 <<
"Ignoring minfilter request\n";
1143 }
else if (egg_ignore_mipmaps) {
1144 egg2pg_cat.warning()
1145 <<
"Ignoring mipmap request\n";
1152 case EggTexture::FT_nearest_mipmap_linear:
1153 if (egg_ignore_filters) {
1154 egg2pg_cat.warning()
1155 <<
"Ignoring minfilter request\n";
1157 }
else if (egg_ignore_mipmaps) {
1158 egg2pg_cat.warning()
1159 <<
"Ignoring mipmap request\n";
1166 case EggTexture::FT_linear_mipmap_linear:
1167 if (egg_ignore_filters) {
1168 egg2pg_cat.warning()
1169 <<
"Ignoring minfilter request\n";
1171 }
else if (egg_ignore_mipmaps) {
1172 egg2pg_cat.warning()
1173 <<
"Ignoring mipmap request\n";
1180 case EggTexture::FT_unspecified:
1184 switch (egg_tex->get_magfilter()) {
1185 case EggTexture::FT_nearest:
1186 case EggTexture::FT_nearest_mipmap_nearest:
1187 case EggTexture::FT_nearest_mipmap_linear:
1191 case EggTexture::FT_linear:
1192 case EggTexture::FT_linear_mipmap_nearest:
1193 case EggTexture::FT_linear_mipmap_linear:
1194 if (egg_ignore_filters) {
1195 egg2pg_cat.warning()
1196 <<
"Ignoring magfilter request\n";
1203 case EggTexture::FT_unspecified:
1212 switch (egg_tex->get_format()) {
1213 case EggTexture::F_red:
1216 case EggTexture::F_green:
1219 case EggTexture::F_blue:
1222 case EggTexture::F_alpha:
1225 case EggTexture::F_luminance:
1229 case EggTexture::F_unspecified:
1233 egg2pg_cat.warning()
1234 <<
"Ignoring inappropriate format " << egg_tex->get_format()
1235 <<
" for 1-component texture " << egg_tex->get_name() <<
"\n";
1239 switch (egg_tex->get_format()) {
1240 case EggTexture::F_luminance_alpha:
1244 case EggTexture::F_luminance_alphamask:
1245 tex->
set_format(Texture::F_luminance_alphamask);
1248 case EggTexture::F_unspecified:
1252 egg2pg_cat.warning()
1253 <<
"Ignoring inappropriate format " << egg_tex->get_format()
1254 <<
" for 2-component texture " << egg_tex->get_name() <<
"\n";
1258 switch (egg_tex->get_format()) {
1259 case EggTexture::F_rgb:
1262 case EggTexture::F_rgb12:
1267 egg2pg_cat.warning()
1268 <<
"Ignoring inappropriate format " << egg_tex->get_format()
1269 <<
" for 8-bit texture " << egg_tex->get_name() <<
"\n";
1272 case EggTexture::F_rgb8:
1273 case EggTexture::F_rgba8:
1279 case EggTexture::F_rgb5:
1282 case EggTexture::F_rgb332:
1286 case EggTexture::F_unspecified:
1290 egg2pg_cat.warning()
1291 <<
"Ignoring inappropriate format " << egg_tex->get_format()
1292 <<
" for 3-component texture " << egg_tex->get_name() <<
"\n";
1296 switch (egg_tex->get_format()) {
1297 case EggTexture::F_rgba:
1300 case EggTexture::F_rgbm:
1303 case EggTexture::F_rgba12:
1308 egg2pg_cat.warning()
1309 <<
"Ignoring inappropriate format " << egg_tex->get_format()
1310 <<
" for 8-bit texture " << egg_tex->get_name() <<
"\n";
1313 case EggTexture::F_rgba8:
1316 case EggTexture::F_rgba4:
1319 case EggTexture::F_rgba5:
1323 case EggTexture::F_unspecified:
1327 egg2pg_cat.warning()
1328 <<
"Ignoring inappropriate format " << egg_tex->get_format()
1329 <<
" for 4-component texture " << egg_tex->get_name() <<
"\n";
1333 switch (egg_tex->get_quality_level()) {
1334 case EggTexture::QL_unspecified:
1335 case EggTexture::QL_default:
1339 case EggTexture::QL_fastest:
1343 case EggTexture::QL_normal:
1347 case EggTexture::QL_best:
1361 Texture::CompressionMode EggLoader::
1362 convert_compression_mode(EggTexture::CompressionMode compression_mode)
const {
1363 switch (compression_mode) {
1364 case EggTexture::CM_off:
1365 return Texture::CM_off;
1367 case EggTexture::CM_on:
1368 return Texture::CM_on;
1370 case EggTexture::CM_fxt1:
1371 return Texture::CM_fxt1;
1373 case EggTexture::CM_dxt1:
1374 return Texture::CM_dxt1;
1376 case EggTexture::CM_dxt2:
1377 return Texture::CM_dxt2;
1379 case EggTexture::CM_dxt3:
1380 return Texture::CM_dxt3;
1382 case EggTexture::CM_dxt4:
1383 return Texture::CM_dxt4;
1385 case EggTexture::CM_dxt5:
1386 return Texture::CM_dxt5;
1388 case EggTexture::CM_default:
1389 return Texture::CM_default;
1392 egg2pg_cat.warning()
1393 <<
"Unexpected texture compression flag: " << (int)compression_mode <<
"\n";
1394 return Texture::CM_default;
1404 SamplerState::WrapMode EggLoader::
1405 convert_wrap_mode(EggTexture::WrapMode wrap_mode)
const {
1406 switch (wrap_mode) {
1407 case EggTexture::WM_clamp:
1408 return SamplerState::WM_clamp;
1410 case EggTexture::WM_repeat:
1411 return SamplerState::WM_repeat;
1413 case EggTexture::WM_mirror:
1414 return SamplerState::WM_mirror;
1416 case EggTexture::WM_mirror_once:
1417 return SamplerState::WM_mirror_once;
1419 case EggTexture::WM_border_color:
1420 return SamplerState::WM_border_color;
1422 case EggTexture::WM_unspecified:
1423 return SamplerState::WM_repeat;
1426 egg2pg_cat.warning()
1427 <<
"Unexpected texture wrap flag: " << (int)wrap_mode <<
"\n";
1428 return SamplerState::WM_repeat;
1438 make_texture_stage(
const EggTexture *egg_tex) {
1446 (egg_tex->get_env_type() == EggTexture::ET_unspecified ||
1447 egg_tex->get_env_type() == EggTexture::ET_modulate) &&
1448 egg_tex->get_combine_mode(EggTexture::CC_rgb) == EggTexture::CM_unspecified &&
1449 egg_tex->get_combine_mode(EggTexture::CC_alpha) == EggTexture::CM_unspecified &&
1459 switch (egg_tex->get_env_type()) {
1460 case EggTexture::ET_modulate:
1461 stage->set_mode(TextureStage::M_modulate);
1464 case EggTexture::ET_decal:
1465 stage->set_mode(TextureStage::M_decal);
1468 case EggTexture::ET_blend:
1469 stage->set_mode(TextureStage::M_blend);
1472 case EggTexture::ET_replace:
1473 stage->set_mode(TextureStage::M_replace);
1476 case EggTexture::ET_add:
1477 stage->set_mode(TextureStage::M_add);
1480 case EggTexture::ET_blend_color_scale:
1481 stage->set_mode(TextureStage::M_blend_color_scale);
1484 case EggTexture::ET_modulate_glow:
1485 stage->set_mode(TextureStage::M_modulate_glow);
1488 case EggTexture::ET_modulate_gloss:
1489 stage->set_mode(TextureStage::M_modulate_gloss);
1492 case EggTexture::ET_normal:
1493 stage->set_mode(TextureStage::M_normal);
1496 case EggTexture::ET_normal_height:
1497 stage->set_mode(TextureStage::M_normal_height);
1500 case EggTexture::ET_glow:
1501 stage->set_mode(TextureStage::M_glow);
1504 case EggTexture::ET_gloss:
1505 stage->set_mode(TextureStage::M_gloss);
1508 case EggTexture::ET_height:
1509 stage->set_mode(TextureStage::M_height);
1512 case EggTexture::ET_selector:
1513 stage->set_mode(TextureStage::M_selector);
1516 case EggTexture::ET_normal_gloss:
1517 stage->set_mode(TextureStage::M_normal_gloss);
1520 case EggTexture::ET_unspecified:
1524 switch (egg_tex->get_combine_mode(EggTexture::CC_rgb)) {
1525 case EggTexture::CM_replace:
1526 stage->set_combine_rgb(get_combine_mode(egg_tex, EggTexture::CC_rgb),
1527 get_combine_source(egg_tex, EggTexture::CC_rgb, 0),
1528 get_combine_operand(egg_tex, EggTexture::CC_rgb, 0));
1531 case EggTexture::CM_modulate:
1532 case EggTexture::CM_add:
1533 case EggTexture::CM_add_signed:
1534 case EggTexture::CM_subtract:
1535 case EggTexture::CM_dot3_rgb:
1536 case EggTexture::CM_dot3_rgba:
1537 stage->set_combine_rgb(get_combine_mode(egg_tex, EggTexture::CC_rgb),
1538 get_combine_source(egg_tex, EggTexture::CC_rgb, 0),
1539 get_combine_operand(egg_tex, EggTexture::CC_rgb, 0),
1540 get_combine_source(egg_tex, EggTexture::CC_rgb, 1),
1541 get_combine_operand(egg_tex, EggTexture::CC_rgb, 1));
1544 case EggTexture::CM_interpolate:
1545 stage->set_combine_rgb(get_combine_mode(egg_tex, EggTexture::CC_rgb),
1546 get_combine_source(egg_tex, EggTexture::CC_rgb, 0),
1547 get_combine_operand(egg_tex, EggTexture::CC_rgb, 0),
1548 get_combine_source(egg_tex, EggTexture::CC_rgb, 1),
1549 get_combine_operand(egg_tex, EggTexture::CC_rgb, 1),
1550 get_combine_source(egg_tex, EggTexture::CC_rgb, 2),
1551 get_combine_operand(egg_tex, EggTexture::CC_rgb, 2));
1554 case EggTexture::CM_unspecified:
1558 switch (egg_tex->get_combine_mode(EggTexture::CC_alpha)) {
1559 case EggTexture::CM_replace:
1560 stage->set_combine_alpha(get_combine_mode(egg_tex, EggTexture::CC_alpha),
1561 get_combine_source(egg_tex, EggTexture::CC_alpha, 0),
1562 get_combine_operand(egg_tex, EggTexture::CC_alpha, 0));
1565 case EggTexture::CM_modulate:
1566 case EggTexture::CM_add:
1567 case EggTexture::CM_add_signed:
1568 case EggTexture::CM_subtract:
1569 stage->set_combine_alpha(get_combine_mode(egg_tex, EggTexture::CC_alpha),
1570 get_combine_source(egg_tex, EggTexture::CC_alpha, 0),
1571 get_combine_operand(egg_tex, EggTexture::CC_alpha, 0),
1572 get_combine_source(egg_tex, EggTexture::CC_alpha, 1),
1573 get_combine_operand(egg_tex, EggTexture::CC_alpha, 1));
1576 case EggTexture::CM_interpolate:
1577 stage->set_combine_alpha(get_combine_mode(egg_tex, EggTexture::CC_alpha),
1578 get_combine_source(egg_tex, EggTexture::CC_alpha, 0),
1579 get_combine_operand(egg_tex, EggTexture::CC_alpha, 0),
1580 get_combine_source(egg_tex, EggTexture::CC_alpha, 1),
1581 get_combine_operand(egg_tex, EggTexture::CC_alpha, 1),
1582 get_combine_source(egg_tex, EggTexture::CC_alpha, 2),
1583 get_combine_operand(egg_tex, EggTexture::CC_alpha, 2));
1586 case EggTexture::CM_unspecified:
1587 case EggTexture::CM_dot3_rgb:
1588 case EggTexture::CM_dot3_rgba:
1594 PT(InternalName) name =
1595 InternalName::get_texcoord_name(egg_tex->
get_uv_name());
1596 stage->set_texcoord_name(name);
1632 separate_switches(
EggNode *egg_node) {
1633 bool parent_has_switch =
false;
1634 if (egg_node->
is_of_type(EggGroup::get_class_type())) {
1636 parent_has_switch = egg_group->get_switch_flag();
1639 if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
1642 EggGroupNode::iterator ci;
1643 ci = egg_group->begin();
1644 while (ci != egg_group->end()) {
1645 EggGroupNode::iterator cnext;
1650 if (parent_has_switch &&
1651 child->is_of_type(EggPrimitive::get_class_type())) {
1654 egg_group->
replace(ci, new_group.p());
1655 new_group->add_child(child);
1658 separate_switches(child);
1674 emulate_bface(
EggNode *egg_node) {
1675 if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
1679 EggGroupNode::iterator ci;
1680 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1682 if (child->is_of_type(EggPolygon::get_class_type())) {
1688 dup_poly->reverse_vertex_ordering();
1689 if (dup_poly->has_normal()) {
1690 dup_poly->set_normal(-dup_poly->get_normal());
1694 EggPolygon::iterator vi;
1695 for (vi = dup_poly->begin(); vi != dup_poly->end(); ++vi) {
1697 if (vertex->has_normal()) {
1699 dup_vertex.set_normal(-dup_vertex.get_normal());
1701 if (new_vertex != vertex) {
1703 dup_poly->replace(vi, new_vertex);
1707 dup_prims->add_child(dup_poly);
1711 emulate_bface(child);
1727 if (egg_node->
is_of_type(EggBin::get_class_type())) {
1728 return make_node(DCAST(
EggBin, egg_node), parent);
1729 }
else if (egg_node->
is_of_type(EggGroup::get_class_type())) {
1730 return make_node(DCAST(
EggGroup, egg_node), parent);
1731 }
else if (egg_node->
is_of_type(EggTable::get_class_type())) {
1732 return make_node(DCAST(
EggTable, egg_node), parent);
1733 }
else if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
1734 return make_node(DCAST(
EggGroupNode, egg_node), parent);
1750 switch (egg_bin->get_bin_number()) {
1751 case EggBinner::BN_polyset:
1752 case EggBinner::BN_patches:
1753 make_polyset(egg_bin, parent, NULL, _dynamic_override, _dynamic_override_char_maker);
1756 case EggBinner::BN_lod:
1757 return make_lod(egg_bin, parent);
1759 case EggBinner::BN_nurbs_surface:
1761 nassertr(!egg_bin->empty(), NULL);
1764 DCAST_INTO_R(egg_nurbs, child, NULL);
1766 make_nurbs_surface(egg_nurbs, parent, mat);
1770 case EggBinner::BN_nurbs_curve:
1772 nassertr(!egg_bin->empty(), NULL);
1775 DCAST_INTO_R(egg_nurbs, child, NULL);
1777 make_nurbs_curve(egg_nurbs, parent, mat);
1781 case EggBinner::BN_none:
1796 PT(
LODNode) lod_node = LODNode::make_default_lod(egg_bin->get_name());
1800 EggGroup::const_iterator ci;
1801 for (ci = egg_bin->begin(); ci != egg_bin->end(); ++ci) {
1803 instances.push_back(instance);
1808 sort(instances.begin(), instances.end());
1810 if (!instances.empty()) {
1813 lod_node->set_center(LCAST(PN_stdfloat, instances[0]._d->_center));
1816 for (
size_t i = 0; i < instances.size(); i++) {
1819 make_node(instance._egg_node, lod_node);
1823 nassertr(lod_node->get_center().almost_equal
1824 (LCAST(PN_stdfloat, instance._d->_center), 0.01), NULL);
1827 lod_node->add_switch(instance._d->_switch_in, instance._d->_switch_out);
1830 _groups[egg_bin] = lod_node;
1831 return create_group_arc(egg_bin, parent, lod_node);
1843 if (egg_group->get_dart_type() != EggGroup::DT_none) {
1845 bool structured = (egg_group->get_dart_type() == EggGroup::DT_structured);
1849 node = char_maker.make_node();
1853 _dynamic_override =
true;
1854 _dynamic_override_char_maker = &char_maker;
1855 EggGroup::const_iterator ci;
1856 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1857 make_node(*ci, node);
1859 _dynamic_override_char_maker = NULL;
1860 _dynamic_override =
false;
1863 }
else if (egg_group->get_cs_type() != EggGroup::CST_none) {
1867 make_collision_solids(egg_group, egg_group, (
CollisionNode *)node.p());
1872 if ((egg_group->get_collide_flags() & EggGroup::CF_keep) != 0) {
1877 parent->add_child(combined);
1878 combined->add_child(node);
1881 EggGroup::const_iterator ci;
1882 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1883 make_node(*ci, combined);
1887 node = create_group_arc(egg_group, parent, node);
1890 }
else if (egg_group->get_portal_flag()) {
1897 set_portal_polygon(egg_group, pnode);
1899 egg2pg_cat.warning()
1900 <<
"Portal " << egg_group->get_name() <<
" has no vertices!\n";
1903 }
else if (egg_group->get_occluder_flag()) {
1910 set_occluder_polygon(egg_group, pnode);
1912 egg2pg_cat.warning()
1913 <<
"Occluder " << egg_group->get_name() <<
" has no vertices!\n";
1916 }
else if (egg_group->get_polylight_flag()) {
1924 if (!make_sphere(egg_group, EggGroup::CF_none, center, radius, color)) {
1925 egg2pg_cat.warning()
1926 <<
"Polylight " << egg_group->get_name() <<
" make_sphere failed!\n";
1937 }
else if (egg_group->get_switch_flag()) {
1938 if (egg_group->get_switch_fps() != 0.0) {
1941 ((
SequenceNode *)node.p())->set_frame_rate(egg_group->get_switch_fps());
1942 _sequences.insert(node);
1945 node =
new SwitchNode(egg_group->get_name());
1948 EggGroup::const_iterator ci;
1949 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1950 make_node(*ci, node);
1952 }
else if (egg_group->has_scrolling_uvs()) {
1953 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());
1955 EggGroup::const_iterator ci;
1956 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1957 make_node(*ci, node);
1960 }
else if (egg_group->get_model_flag() || egg_group->
has_dcs_type()) {
1962 node =
new ModelNode(egg_group->get_name());
1963 switch (egg_group->get_dcs_type()) {
1964 case EggGroup::DC_net:
1965 DCAST(
ModelNode, node)->set_preserve_transform(ModelNode::PT_net);
1968 case EggGroup::DC_no_touch:
1969 DCAST(
ModelNode, node)->set_preserve_transform(ModelNode::PT_no_touch);
1972 case EggGroup::DC_local:
1973 case EggGroup::DC_default:
1974 DCAST(
ModelNode, node)->set_preserve_transform(ModelNode::PT_local);
1977 case EggGroup::DC_none:
1978 case EggGroup::DC_unspecified:
1982 EggGroup::const_iterator ci;
1983 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
1984 make_node(*ci, node);
1992 bool all_polysets =
false;
1993 bool any_hidden =
false;
1998 check_for_polysets(egg_group, all_polysets, any_hidden);
2001 if (all_polysets && !any_hidden) {
2002 node =
new GeomNode(egg_group->get_name());
2004 node =
new PandaNode(egg_group->get_name());
2007 EggGroup::const_iterator ci;
2008 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2009 make_node(*ci, node);
2019 for (
int gri = 0; gri < num_group_refs; ++gri) {
2021 Groups::const_iterator gi = _groups.find(group_ref);
2022 if (gi != _groups.end()) {
2024 node->add_child(node_ref);
2028 _groups[egg_group] = node;
2029 return create_group_arc(egg_group, parent, node);
2042 parent->add_child(node);
2046 CPT(TransformState) transform = make_transform(egg_group);
2052 switch (egg_group->get_billboard_type()) {
2053 case EggGroup::BT_point_camera_relative:
2054 node->
set_effect(BillboardEffect::make_point_eye());
2057 case EggGroup::BT_point_world_relative:
2058 node->
set_effect(BillboardEffect::make_point_world());
2061 case EggGroup::BT_axis:
2062 node->
set_effect(BillboardEffect::make_axis());
2065 case EggGroup::BT_none:
2069 if (egg_group->get_decal_flag()) {
2070 if (egg_ignore_decals) {
2072 <<
"Ignoring decal flag on " << egg_group->get_name() <<
"\n";
2080 _decals.insert(node);
2084 EggGroup::TagData::const_iterator ti;
2086 node->
set_tag((*ti).first, (*ti).second);
2089 if (egg_group->get_blend_mode() != EggGroup::BM_unspecified &&
2090 egg_group->get_blend_mode() != EggGroup::BM_none) {
2092 ColorBlendAttrib::Mode mode = get_color_blend_mode(egg_group->get_blend_mode());
2093 ColorBlendAttrib::Operand a = get_color_blend_operand(egg_group->get_blend_operand_a());
2094 ColorBlendAttrib::Operand b = get_color_blend_operand(egg_group->get_blend_operand_b());
2096 node->
set_attrib(ColorBlendAttrib::make(mode, a, b, color));
2103 if (egg_group->has_collide_mask()) {
2104 def._from_collide_mask = egg_group->get_collide_mask();
2105 def._into_collide_mask = egg_group->get_collide_mask();
2107 DeferredNodeProperty::F_has_from_collide_mask |
2108 DeferredNodeProperty::F_has_into_collide_mask;
2110 if (egg_group->has_from_collide_mask()) {
2111 def._from_collide_mask = egg_group->get_from_collide_mask();
2112 def._flags |= DeferredNodeProperty::F_has_from_collide_mask;
2114 if (egg_group->has_into_collide_mask()) {
2115 def._into_collide_mask = egg_group->get_into_collide_mask();
2116 def._flags |= DeferredNodeProperty::F_has_into_collide_mask;
2119 if (def._flags != 0) {
2120 _deferred_nodes[node] = def;
2133 if (egg_table->get_table_type() != EggTable::TT_bundle) {
2136 return make_node(DCAST(
EggGroupNode, egg_table), parent);
2143 parent->add_child(node);
2157 EggGroupNode::const_iterator ci;
2158 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2159 make_node(*ci, node);
2162 parent->add_child(node);
2174 check_for_polysets(
EggGroup *egg_group,
bool &all_polysets,
bool &any_hidden) {
2175 all_polysets = (!egg_group->empty());
2178 EggGroup::const_iterator ci;
2179 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2180 if ((*ci)->is_of_type(EggBin::get_class_type())) {
2182 if (egg_bin->get_bin_number() == EggBinner::BN_polyset) {
2186 EggGroup::const_iterator bci = egg_bin->begin();
2187 nassertv(bci != egg_bin->end());
2189 DCAST_INTO_V(first_prim, (*bci));
2191 DCAST_INTO_V(render_state, first_prim->get_user_data(EggRenderState::get_class_type()));
2193 if (render_state->_hidden) {
2197 all_polysets =
false;
2200 }
else if ((*ci)->is_of_type(EggGroup::get_class_type())) {
2204 all_polysets =
false;
2223 bool ignore_color) {
2224 VertexPoolTransform vpt;
2225 vpt._vertex_pool = vertex_pool;
2226 vpt._bake_in_uvs = render_state->_bake_in_uvs;
2227 vpt._transform = transform;
2229 VertexPoolData::iterator di;
2230 di = _vertex_pool_data.find(vpt);
2231 if (di != _vertex_pool_data.end()) {
2232 return (*di).second;
2235 PT(GeomVertexArrayFormat) array_format =
new GeomVertexArrayFormat;
2236 array_format->add_column
2238 Geom::NT_stdfloat, Geom::C_point);
2241 array_format->add_column
2242 (InternalName::get_normal(), 3,
2243 Geom::NT_stdfloat, Geom::C_normal);
2246 if (!ignore_color) {
2250 array_format->add_column(InternalName::get_color(), 1,
2251 Geom::NT_packed_dabc, Geom::C_color);
2253 array_format->add_column(InternalName::get_color(), 4,
2254 Geom::NT_uint8, Geom::C_color);
2258 vector_string uv_names, uvw_names, tbn_names;
2259 vertex_pool->
get_uv_names(uv_names, uvw_names, tbn_names);
2260 vector_string::const_iterator ni;
2261 for (ni = uv_names.begin(); ni != uv_names.end(); ++ni) {
2262 string name = (*ni);
2264 PT(InternalName) iname = InternalName::get_texcoord_name(name);
2266 if (find(uvw_names.begin(), uvw_names.end(), name) != uvw_names.end()) {
2268 array_format->add_column
2269 (iname, 3, Geom::NT_stdfloat, Geom::C_texcoord);
2271 array_format->add_column
2272 (iname, 2, Geom::NT_stdfloat, Geom::C_texcoord);
2275 for (ni = tbn_names.begin(); ni != tbn_names.end(); ++ni) {
2276 string name = (*ni);
2278 PT(InternalName) iname_t = InternalName::get_tangent_name(name);
2279 PT(InternalName) iname_b = InternalName::get_binormal_name(name);
2281 array_format->add_column
2282 (iname_t, 3, Geom::NT_stdfloat, Geom::C_vector);
2283 array_format->add_column
2284 (iname_b, 3, Geom::NT_stdfloat, Geom::C_vector);
2287 vector_string aux_names;
2289 for (ni = aux_names.begin(); ni != aux_names.end(); ++ni) {
2290 string name = (*ni);
2291 PT(InternalName) iname = InternalName::make(name);
2292 array_format->add_column
2293 (iname, 4, Geom::NT_stdfloat, Geom::C_other);
2296 PT(GeomVertexFormat) temp_format =
new GeomVertexFormat(array_format);
2299 string name = _data->get_egg_filename().get_basename_wo_extension();
2311 temp_format->set_animation(animation);
2313 PT(GeomVertexArrayFormat) anim_array_format =
new GeomVertexArrayFormat;
2314 anim_array_format->add_column
2315 (InternalName::get_transform_blend(), 1,
2316 Geom::NT_uint16, Geom::C_index, 0, 2);
2317 temp_format->add_array(anim_array_format);
2321 for (vi = vertex_pool->
begin(); vi != vertex_pool->
end(); ++vi) {
2324 EggMorphVertexList::const_iterator mvi;
2325 for (mvi = vertex->_dxyzs.begin(); mvi != vertex->_dxyzs.end(); ++mvi) {
2326 slider_names[(*mvi).get_name()].set_bit(vertex->
get_index());
2327 record_morph(anim_array_format, character_maker, (*mvi).
get_name(),
2328 InternalName::get_vertex(), 3);
2330 if (vertex->has_normal()) {
2331 EggMorphNormalList::const_iterator mni;
2332 for (mni = vertex->_dnormals.begin(); mni != vertex->_dnormals.end(); ++mni) {
2333 slider_names[(*mni).get_name()].set_bit(vertex->
get_index());
2334 record_morph(anim_array_format, character_maker, (*mni).
get_name(),
2335 InternalName::get_normal(), 3);
2338 if (!ignore_color && vertex->has_color()) {
2339 EggMorphColorList::const_iterator mci;
2340 for (mci = vertex->_drgbas.begin(); mci != vertex->_drgbas.end(); ++mci) {
2341 slider_names[(*mci).get_name()].set_bit(vertex->
get_index());
2342 record_morph(anim_array_format, character_maker, (*mci).
get_name(),
2343 InternalName::get_color(), 4);
2349 string name = egg_uv->get_name();
2350 bool has_w = (find(uvw_names.begin(), uvw_names.end(), name) != uvw_names.end());
2351 PT(InternalName) iname = InternalName::get_texcoord_name(name);
2353 EggMorphTexCoordList::const_iterator mti;
2354 for (mti = egg_uv->_duvs.begin(); mti != egg_uv->_duvs.end(); ++mti) {
2355 slider_names[(*mti).get_name()].set_bit(vertex->
get_index());
2356 record_morph(anim_array_format, character_maker, (*mti).
get_name(),
2357 iname, has_w ? 3 : 2);
2362 if (!slider_names.empty()) {
2368 for (si = slider_names.begin(); si != slider_names.end(); ++si) {
2370 slider_table->add_slider(slider, (*si).second);
2376 name = character_maker->
get_name();
2379 temp_format->maybe_align_columns_for_animation();
2381 CPT(GeomVertexFormat) format =
2382 GeomVertexFormat::register_format(temp_format);
2391 vertex_data->reserve_num_rows(vertex_pool->
size());
2393 vertex_data->set_transform_blend_table(blend_table);
2395 vertex_data->set_slider_table(SliderTable::register_table(slider_table));
2400 for (vi = vertex_pool->
begin(); vi != vertex_pool->
end(); ++vi) {
2409 EggMorphVertexList::const_iterator mvi;
2410 for (mvi = vertex->_dxyzs.begin(); mvi != vertex->_dxyzs.end(); ++mvi) {
2412 CPT(InternalName) delta_name =
2413 InternalName::get_morph(InternalName::get_vertex(), morph.get_name());
2415 gvw.
add_data3d(morph.get_offset() * transform);
2419 if (vertex->has_normal()) {
2421 LNormald orig_normal = vertex->get_normal();
2422 LNormald transformed_normal = normalize(orig_normal * transform);
2426 EggMorphNormalList::const_iterator mni;
2427 for (mni = vertex->_dnormals.begin(); mni != vertex->_dnormals.end(); ++mni) {
2429 CPT(InternalName) delta_name =
2430 InternalName::get_morph(InternalName::get_normal(), morph.get_name());
2432 LNormald morphed_normal = orig_normal + morph.get_offset();
2433 LNormald transformed_morphed_normal = normalize(morphed_normal * transform);
2434 LVector3d delta = transformed_morphed_normal - transformed_normal;
2440 if (!ignore_color && vertex->has_color()) {
2445 EggMorphColorList::const_iterator mci;
2446 for (mci = vertex->_drgbas.begin(); mci != vertex->_drgbas.end(); ++mci) {
2448 CPT(InternalName) delta_name =
2449 InternalName::get_morph(InternalName::get_color(), morph.get_name());
2462 string name = egg_uv->get_name();
2463 PT(InternalName) iname = InternalName::get_texcoord_name(name);
2466 BakeInUVs::const_iterator buv = render_state->_bake_in_uvs.find(iname);
2467 if (buv != render_state->_bake_in_uvs.end()) {
2469 uvw = uvw * (*buv).second->get_transform3d();
2475 EggMorphTexCoordList::const_iterator mti;
2476 for (mti = egg_uv->_duvs.begin(); mti != egg_uv->_duvs.end(); ++mti) {
2478 CPT(InternalName) delta_name =
2479 InternalName::get_morph(iname, morph.get_name());
2482 if (buv != render_state->_bake_in_uvs.end()) {
2484 duvw = (new_uvw * (*buv).second->get_transform3d()) - uvw;
2492 if (egg_uv->has_tangent() && egg_uv->has_binormal()) {
2493 PT(InternalName) iname = InternalName::get_tangent_name(name);
2496 LVector3d tangent = egg_uv->get_tangent();
2497 LVector3d binormal = egg_uv->get_binormal();
2499 gvw.
set_column(InternalName::get_binormal_name(name));
2510 string name = egg_aux->get_name();
2511 PT(InternalName) iname = InternalName::make(name);
2519 gvw.
set_column(InternalName::get_transform_blend());
2524 bool inserted = _vertex_pool_data.insert
2525 (VertexPoolData::value_type(vpt, vertex_data)).second;
2526 nassertr(inserted, vertex_data);
2545 for (vi = vertex_pool->
begin(); vi != vertex_pool->
end(); ++vi) {
2559 double quantize = egg_vertex_membership_quantize;
2560 EggVertex::GroupRef::const_iterator gri;
2564 if (quantize != 0.0) {
2565 membership = cfloor(membership / quantize + 0.5) * quantize;
2573 if (egg_vertex_max_num_joints >= 0) {
2578 int table_index = blend_table->
add_blend(blend);
2594 record_morph(GeomVertexArrayFormat *array_format,
2596 const string &morph_name, InternalName *column_name,
2597 int num_components) {
2598 PT(InternalName) delta_name =
2599 InternalName::get_morph(column_name, morph_name);
2600 if (!array_format->has_column(delta_name)) {
2601 array_format->add_column
2602 (delta_name, num_components,
2603 Geom::NT_stdfloat, Geom::C_morph_delta);
2617 bool has_overall_color,
const LColor &overall_color) {
2619 if (egg_prim->
is_of_type(EggPolygon::get_class_type())) {
2620 if (egg_prim->size() == 3) {
2624 }
else if (egg_prim->
is_of_type(EggTriangleStrip::get_class_type())) {
2627 }
else if (egg_prim->
is_of_type(EggTriangleFan::get_class_type())) {
2630 }
else if (egg_prim->
is_of_type(EggLine::get_class_type())) {
2631 if (egg_prim->size() == 2) {
2632 primitive =
new GeomLines(Geom::UH_static);
2637 }
else if (egg_prim->
is_of_type(EggPoint::get_class_type())) {
2640 }
else if (egg_prim->
is_of_type(EggPatch::get_class_type())) {
2641 int num_vertices = egg_prim->size();
2642 primitive =
new GeomPatches(num_vertices, Geom::UH_static);
2647 egg2pg_cat.warning()
2648 <<
"Ignoring " << egg_prim->get_type() <<
"\n";
2652 if (render_state->_flat_shaded) {
2653 primitive->set_shade_model(GeomPrimitive::SM_flat_first_vertex);
2655 }
else if (egg_prim->
get_shading() == EggPrimitive::S_overall) {
2656 primitive->set_shade_model(GeomPrimitive::SM_uniform);
2659 primitive->set_shade_model(GeomPrimitive::SM_smooth);
2664 PrimitiveUnifier pu(primitive);
2665 pair<UniquePrimitives::iterator, bool> result =
2666 unique_primitives.insert(UniquePrimitives::value_type(pu, primitive));
2668 if (result.second) {
2670 primitives.push_back(primitive);
2672 if (egg2pg_cat.is_debug()) {
2674 <<
"First primitive of type " << primitive->get_type()
2675 <<
": " << primitive <<
"\n";
2683 if (orig_prim->
get_num_vertices() + egg_prim->size() <= (
unsigned int)egg_max_indices) {
2684 primitive = orig_prim;
2686 }
else if (orig_prim != primitive) {
2689 (*result.first).second = primitive;
2691 if (egg2pg_cat.is_debug()) {
2693 <<
"Next primitive of type " << primitive->get_type()
2694 <<
": " << primitive <<
"\n";
2696 primitives.push_back(primitive);
2700 EggPrimitive::const_iterator vi;
2701 for (vi = egg_prim->begin(); vi != egg_prim->end(); ++vi) {
2702 primitive->add_vertex((*vi)->get_index());
2704 primitive->close_primitive();
2717 PT(
EggPolygon) poly = find_first_polygon(egg_group);
2719 LMatrix4d mat = poly->get_vertex_to_node();
2721 EggPolygon::const_iterator vi;
2722 for (vi = poly->begin(); vi != poly->end(); ++vi) {
2723 LVertexd vert = (*vi)->get_pos3() * mat;
2737 PT(
EggPolygon) poly = find_first_polygon(egg_group);
2739 if (poly->size() != 4) {
2741 <<
"Invalid number of vertices for " << egg_group->get_name() <<
"\n";
2743 LMatrix4d mat = poly->get_vertex_to_node();
2745 EggPolygon::const_iterator vi;
2746 LPoint3d v0 = (*poly)[0]->get_pos3() * mat;
2747 LPoint3d v1 = (*poly)[1]->get_pos3() * mat;
2748 LPoint3d v2 = (*poly)[2]->get_pos3() * mat;
2749 LPoint3d v3 = (*poly)[3]->get_pos3() * mat;
2751 LCAST(PN_stdfloat, v1),
2752 LCAST(PN_stdfloat, v2),
2753 LCAST(PN_stdfloat, v3));
2755 if (poly->get_bface_flag()) {
2769 find_first_polygon(
EggGroup *egg_group) {
2771 EggGroup::const_iterator ci;
2772 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2773 if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
2781 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2782 if ((*ci)->is_of_type(EggGroup::get_class_type())) {
2784 PT(
EggPolygon) found = find_first_polygon(child_group);
2804 make_sphere(
EggGroup *egg_group, EggGroup::CollideFlags flags,
2806 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
2807 if (geom_group != (
EggGroup *)NULL) {
2811 EggGroup::const_iterator ci;
2812 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
2813 if ((*ci)->is_of_type(EggPrimitive::get_class_type())) {
2815 EggPrimitive::const_iterator pi;
2816 for (pi = prim->begin(); pi != prim->end(); ++pi) {
2817 vertices.insert(*pi);
2823 int num_vertices = 0;
2827 for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
2833 if (num_vertices > 0) {
2834 d_center /= (double)num_vertices;
2838 double radius2 = 0.0;
2839 for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
2846 center = LCAST(PN_stdfloat, d_center);
2847 radius = sqrtf(radius2);
2850 vi = vertices.begin();
2867 make_box(
EggGroup *egg_group, EggGroup::CollideFlags flags,
2869 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
2870 if (geom_group != (
EggGroup *)NULL) {
2874 EggGroup::const_iterator ci;
2875 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
2876 if ((*ci)->is_of_type(EggPrimitive::get_class_type())) {
2878 EggPrimitive::const_iterator pi;
2879 for (pi = prim->begin(); pi != prim->end(); ++pi) {
2880 vertices.insert(*pi);
2887 vi = vertices.begin();
2889 if (vi == vertices.end()) {
2901 for (++vi; vi != vertices.end(); ++vi) {
2904 min_pd.set(min(min_pd[0], pos[0]),
2905 min(min_pd[1], pos[1]),
2906 min(min_pd[2], pos[2]));
2907 max_pd.set(max(max_pd[0], pos[0]),
2908 max(max_pd[1], pos[1]),
2909 max(max_pd[2], pos[2]));
2912 min_p = LCAST(PN_stdfloat, min_pd);
2913 max_p = LCAST(PN_stdfloat, max_pd);
2914 return (min_pd != max_pd);
2929 if (egg_group->get_cs_type() != EggGroup::CST_none) {
2930 start_group = egg_group;
2933 switch (start_group->get_cs_type()) {
2934 case EggGroup::CST_none:
2938 case EggGroup::CST_plane:
2939 make_collision_plane(egg_group, cnode, start_group->get_collide_flags());
2942 case EggGroup::CST_polygon:
2943 make_collision_polygon(egg_group, cnode, start_group->get_collide_flags());
2946 case EggGroup::CST_polyset:
2947 make_collision_polyset(egg_group, cnode, start_group->get_collide_flags());
2950 case EggGroup::CST_sphere:
2951 make_collision_sphere(egg_group, cnode, start_group->get_collide_flags());
2954 case EggGroup::CST_box:
2955 make_collision_box(egg_group, cnode, start_group->get_collide_flags());
2958 case EggGroup::CST_inv_sphere:
2959 make_collision_inv_sphere(egg_group, cnode, start_group->get_collide_flags());
2962 case EggGroup::CST_tube:
2963 make_collision_tube(egg_group, cnode, start_group->get_collide_flags());
2966 case EggGroup::CST_floor_mesh:
2967 make_collision_floor_mesh(egg_group, cnode, start_group->get_collide_flags());
2971 if ((start_group->get_collide_flags() & EggGroup::CF_descend) != 0) {
2973 EggGroup::const_iterator ci;
2974 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
2975 if ((*ci)->is_of_type(EggGroup::get_class_type())) {
2976 make_collision_solids(start_group, DCAST(
EggGroup, *ci), cnode);
2980 egg2pg_cat.warning()
2981 <<
"Using <Collide> without 'descend' is deprecated. 'descend' " 2982 <<
"will become the default in a future version of Panda3D.\n";
2994 EggGroup::CollideFlags flags) {
2995 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
2996 if (geom_group != (
EggGroup *)NULL) {
2997 EggGroup::const_iterator ci;
2998 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
2999 if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
3001 create_collision_plane(DCAST(
EggPolygon, *ci), egg_group);
3003 apply_collision_flags(csplane, flags);
3007 }
else if ((*ci)->is_of_type(EggCompositePrimitive::get_class_type())) {
3011 make_collision_plane(temp_group, cnode, flags);
3029 EggGroup::CollideFlags flags) {
3031 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
3034 if (geom_group != (
EggGroup *)NULL) {
3035 create_collision_floor_mesh(cnode, geom_group,flags);
3047 EggGroup::CollideFlags flags) {
3049 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
3050 if (geom_group != (
EggGroup *)NULL) {
3051 EggGroup::const_iterator ci;
3052 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
3053 if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
3054 create_collision_polygons(cnode, DCAST(
EggPolygon, *ci),
3056 }
else if ((*ci)->is_of_type(EggCompositePrimitive::get_class_type())) {
3060 make_collision_polygon(temp_group, cnode, flags);
3077 EggGroup::CollideFlags flags) {
3078 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
3079 if (geom_group != (
EggGroup *)NULL) {
3080 EggGroup::const_iterator ci;
3081 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
3082 if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
3083 create_collision_polygons(cnode, DCAST(
EggPolygon, *ci),
3085 }
else if ((*ci)->is_of_type(EggCompositePrimitive::get_class_type())) {
3089 make_collision_polyset(temp_group, cnode, flags);
3104 EggGroup::CollideFlags flags) {
3108 if (make_sphere(egg_group, flags, center, radius, dummycolor)) {
3111 apply_collision_flags(cssphere, flags);
3124 EggGroup::CollideFlags flags) {
3128 if (make_box(egg_group, flags, min_p, max_p, dummycolor)) {
3131 apply_collision_flags(csbox, flags);
3144 EggGroup::CollideFlags flags) {
3148 if (make_sphere(egg_group, flags, center, radius, dummycolor)) {
3151 apply_collision_flags(cssphere, flags);
3164 EggGroup::CollideFlags flags) {
3165 EggGroup *geom_group = find_collision_geometry(egg_group, flags);
3166 if (geom_group != (
EggGroup *)NULL) {
3170 EggGroup::const_iterator ci;
3171 for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
3172 if ((*ci)->is_of_type(EggPrimitive::get_class_type())) {
3174 EggPrimitive::const_iterator pi;
3175 for (pi = prim->begin(); pi != prim->end(); ++pi) {
3176 vertices.insert(*pi);
3183 size_t num_vertices = vertices.size();
3184 if (num_vertices != 0) {
3186 vpos.reserve(num_vertices);
3190 for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
3193 vpos.push_back(pos);
3196 center /= (double)num_vertices;
3202 double radius2 = 0.0;
3204 for (i = 0; i < num_vertices; i++) {
3205 double dist2 = (vpos[i] - center).length_squared();
3206 if (dist2 > radius2) {
3217 for (i = 0; i < num_vertices; i++) {
3218 double dist2 = (vpos[i] - far_a).length_squared();
3219 if (dist2 > radius2) {
3238 LPoint3d cap_a_center(0.0, 0.0, 0.0);
3239 LPoint3d cap_b_center(0.0, 0.0, 0.0);
3245 double center_length = (far_a - far_b).length() / 4.0;
3246 double center_length2 = center_length * center_length;
3248 for (i = 0; i < num_vertices; i++) {
3249 double dist2 = (vpos[i] - center).length_squared();
3250 if (dist2 > center_length2) {
3253 double dist_a2 = (vpos[i] - far_a).length_squared();
3254 double dist_b2 = (vpos[i] - far_b).length_squared();
3255 if (dist_a2 < dist_b2) {
3257 cap_a_center += vpos[i];
3261 cap_b_center += vpos[i];
3267 if (num_a > 0 && num_b > 0) {
3268 cap_a_center /= (double)num_a;
3269 cap_b_center /= (double)num_b;
3273 LVector3d axis = cap_b_center - cap_a_center;
3278 if (IS_THRESHOLD_ZERO(axis[0], 0.01)) {
3281 if (IS_THRESHOLD_ZERO(axis[1], 0.01)) {
3284 if (IS_THRESHOLD_ZERO(axis[2], 0.01)) {
3297 look_at(mat, axis,
LVector3d(0.0, 0.0, 1.0), CS_zup_right);
3302 for (i = 0; i < num_vertices; i++) {
3303 vpos[i] = vpos[i] * inv_mat;
3306 double max_radius2 = 0.0;
3309 for (i = 0; i < num_vertices; i++) {
3312 if (radius2 > max_radius2) {
3313 max_radius2 = radius2;
3323 for (i = 0; i < num_vertices; i++) {
3327 if (vpos[i][1] < min_y) {
3330 double factor = sqrt(max_radius2 - radius2);
3331 min_y = min(min_y, vpos[i][1] + factor);
3333 }
else if (vpos[i][1] > max_y) {
3334 double factor = sqrt(max_radius2 - radius2);
3335 max_y = max(max_y, vpos[i][1] - factor);
3339 double length = max_y - min_y;
3340 double radius = sqrt(max_radius2);
3348 new CollisionTube(LCAST(PN_stdfloat, point_a), LCAST(PN_stdfloat, point_b),
3350 apply_collision_flags(cstube, flags);
3365 apply_collision_flags(
CollisionSolid *solid, EggGroup::CollideFlags flags) {
3366 if ((flags & EggGroup::CF_intangible) != 0) {
3369 if ((flags & EggGroup::CF_level) != 0) {
3381 find_collision_geometry(
EggGroup *egg_group, EggGroup::CollideFlags flags) {
3382 if ((flags & EggGroup::CF_descend) != 0) {
3389 EggGroup::const_iterator ci;
3390 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
3391 if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
3399 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
3400 if ((*ci)->is_of_type(EggGroup::get_class_type())) {
3402 if (child_group->get_cs_type() == egg_group->get_cs_type()) {
3422 <<
"Ignoring degenerate collision plane in " << parent_group->get_name()
3428 egg2pg_cat.warning()
3429 <<
"Non-planar polygon defining collision plane in " 3430 << parent_group->get_name()
3435 if (!egg_poly->empty()) {
3436 EggPolygon::const_iterator vi;
3437 vi = egg_poly->begin();
3440 vertices.push_back(LCAST(PN_stdfloat, vert));
3444 while (vi != egg_poly->end()) {
3445 vert = (*vi)->get_pos3();
3447 vertices.push_back(LCAST(PN_stdfloat, vert));
3455 if (vertices.size() < 3) {
3458 LPlane plane(vertices[0], vertices[1], vertices[2]);
3472 EggGroup::CollideFlags flags) {
3478 <<
"Ignoring degenerate collision polygon in " 3479 << parent_group->get_name()
3484 if (group->size() != 1) {
3486 <<
"Triangulating concave or non-planar collision polygon in " 3487 << parent_group->get_name()
3491 EggGroup::iterator ci;
3492 for (ci = group->begin(); ci != group->end(); ++ci) {
3496 if (!poly->empty()) {
3497 EggPolygon::const_iterator vi;
3501 vertices.push_back(LCAST(PN_stdfloat, vert));
3505 while (vi != poly->end()) {
3506 vert = (*vi)->get_pos3();
3508 vertices.push_back(LCAST(PN_stdfloat, vert));
3516 if (vertices.size() >= 3) {
3517 const LVertex *vertices_begin = &vertices[0];
3518 const LVertex *vertices_end = vertices_begin + vertices.size();
3521 if (cspoly->is_valid()) {
3522 apply_collision_flags(cspoly, flags);
3539 EggGroup::CollideFlags flags) {
3544 EggGroup::const_iterator egi;
3545 for (egi = parent_group->begin(); egi != parent_group->end(); ++egi) {
3546 if ((*egi)->is_of_type(EggPolygon::get_class_type())) {
3550 <<
"Ignoring degenerate collision polygon in " 3551 << parent_group->get_name()
3558 if(group->size() == 0) {
3560 <<
"empty collision solid\n";
3566 EggGroup::iterator ci;
3567 for (ci = group->begin(); ci != group->end(); ++ci) {
3569 if (poly->get_num_vertices() == 3) {
3577 triangles.push_back(tri);
3578 }
else if (poly->get_num_vertices() == 4) {
3589 triangles.push_back(tri);
3597 triangles.push_back(tri2);
3606 for (vi = pool.
begin(); vi != pool.
end(); vi++) {
3607 csfloor->add_vertex(LCAST(PN_stdfloat,(*vi)->get_pos3()));
3612 for (ti = triangles.begin(); ti != triangles.end(); ti++) {
3614 csfloor->add_triangle(triangle.p1, triangle.p2, triangle.p3);
3632 DeferredNodes::const_iterator dni;
3633 dni = _deferred_nodes.find(node);
3635 if (dni != _deferred_nodes.end()) {
3644 for (
int i = 0; i < num_children; i++) {
3645 apply_deferred_nodes(node->
get_child(i), next_prop);
3661 expand_all_object_types(
EggNode *egg_node) {
3662 if (egg_node->
is_of_type(EggGroup::get_class_type())) {
3665 if (egg_group->get_num_object_types() != 0) {
3668 if (!expand_object_types(egg_group, expanded, expanded_history)) {
3676 if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
3678 EggGroupNode::const_iterator ci;
3679 ci = egg_group_node->begin();
3680 while (ci != egg_group_node->end()) {
3681 EggGroupNode::const_iterator cnext = ci;
3684 if (!expand_all_object_types(*ci)) {
3686 egg_group_node->erase(ci);
3710 int num_object_types = egg_group->get_num_object_types();
3714 vector_string object_types;
3716 for (i = 0; i < num_object_types; i++) {
3717 object_types.push_back(egg_group->get_object_type(i));
3719 egg_group->clear_object_types();
3721 for (i = 0; i < num_object_types; i++) {
3722 string object_type = object_types[i];
3726 if (!new_expanded.insert(object_type).second) {
3728 <<
"Cycle in ObjectType expansions:\n";
3730 for (pi = expanded_history.begin();
3731 pi != expanded_history.end();
3733 egg2pg_cat.error(
false)
3736 egg2pg_cat.error(
false) << object_type <<
"\n";
3742 new_expanded_history.push_back(object_type);
3744 if (!do_expand_object_type(egg_group, new_expanded,
3745 new_expanded_history, object_type)) {
3763 const string &object_type) {
3768 (
"egg-object-type-" + downcase(object_type),
"");
3769 string egg_syntax = egg_object_type;
3774 if (cmp_nocase_uh(object_type,
"barrier") == 0) {
3775 egg_syntax =
"<Collide> { Polyset descend }";
3777 }
else if (cmp_nocase_uh(object_type,
"solidpoly") == 0) {
3778 egg_syntax =
"<Collide> { Polyset descend solid }";
3780 }
else if (cmp_nocase_uh(object_type,
"turnstile") == 0) {
3781 egg_syntax =
"<Collide> { Polyset descend turnstile }";
3783 }
else if (cmp_nocase_uh(object_type,
"sphere") == 0) {
3784 egg_syntax =
"<Collide> { Sphere descend }";
3786 }
else if (cmp_nocase_uh(object_type,
"tube") == 0) {
3787 egg_syntax =
"<Collide> { Tube descend }";
3789 }
else if (cmp_nocase_uh(object_type,
"trigger") == 0) {
3790 egg_syntax =
"<Collide> { Polyset descend intangible }";
3792 }
else if (cmp_nocase_uh(object_type,
"trigger_sphere") == 0) {
3793 egg_syntax =
"<Collide> { Sphere descend intangible }";
3795 }
else if (cmp_nocase_uh(object_type,
"eye_trigger") == 0) {
3796 egg_syntax =
"<Collide> { Polyset descend intangible center }";
3798 }
else if (cmp_nocase_uh(object_type,
"bubble") == 0) {
3799 egg_syntax =
"<Collide> { Sphere keep descend }";
3801 }
else if (cmp_nocase_uh(object_type,
"ghost") == 0) {
3802 egg_syntax =
"<Scalar> collide-mask { 0 }";
3804 }
else if (cmp_nocase_uh(object_type,
"dcs") == 0) {
3805 egg_syntax =
"<DCS> { 1 }";
3807 }
else if (cmp_nocase_uh(object_type,
"model") == 0) {
3808 egg_syntax =
"<Model> { 1 }";
3810 }
else if (cmp_nocase_uh(object_type,
"none") == 0) {
3814 }
else if (cmp_nocase_uh(object_type,
"backstage") == 0) {
3820 <<
"Unknown ObjectType " << object_type <<
"\n";
3822 egg2pg_cat.debug() <<
"returning true\n";
3827 if (!egg_syntax.empty()) {
3828 if (!egg_group->
parse_egg(egg_syntax)) {
3830 <<
"Error while parsing definition for ObjectType " 3831 << object_type <<
"\n";
3837 if (egg_group->get_num_object_types() != 0) {
3838 if (!expand_object_types(egg_group, expanded, expanded_history)) {
3854 TextureStage::CombineMode EggLoader::
3856 EggTexture::CombineChannel channel) {
3857 switch (egg_tex->get_combine_mode(channel)) {
3858 case EggTexture::CM_unspecified:
3861 case EggTexture::CM_modulate:
3862 return TextureStage::CM_modulate;
3864 case EggTexture::CM_replace:
3865 return TextureStage::CM_replace;
3867 case EggTexture::CM_add:
3868 return TextureStage::CM_add;
3870 case EggTexture::CM_add_signed:
3871 return TextureStage::CM_add_signed;
3873 case EggTexture::CM_interpolate:
3874 return TextureStage::CM_interpolate;
3876 case EggTexture::CM_subtract:
3877 return TextureStage::CM_subtract;
3879 case EggTexture::CM_dot3_rgb:
3880 return TextureStage::CM_dot3_rgb;
3882 case EggTexture::CM_dot3_rgba:
3883 return TextureStage::CM_dot3_rgba;
3886 return TextureStage::CM_undefined;
3895 TextureStage::CombineSource EggLoader::
3896 get_combine_source(
const EggTexture *egg_tex,
3897 EggTexture::CombineChannel channel,
int n) {
3898 switch (egg_tex->get_combine_source(channel, n)) {
3899 case EggTexture::CS_unspecified:
3904 return TextureStage::CS_previous;
3906 return TextureStage::CS_texture;
3908 return TextureStage::CS_constant;
3912 case EggTexture::CS_texture:
3913 return TextureStage::CS_texture;
3915 case EggTexture::CS_constant:
3916 return TextureStage::CS_constant;
3918 case EggTexture::CS_primary_color:
3919 return TextureStage::CS_primary_color;
3921 case EggTexture::CS_previous:
3922 return TextureStage::CS_previous;
3924 case EggTexture::CS_constant_color_scale:
3925 return TextureStage::CS_constant_color_scale;
3927 case EggTexture::CS_last_saved_result:
3928 return TextureStage::CS_last_saved_result;
3931 return TextureStage::CS_undefined;
3940 TextureStage::CombineOperand EggLoader::
3941 get_combine_operand(
const EggTexture *egg_tex,
3942 EggTexture::CombineChannel channel,
int n) {
3943 switch (egg_tex->get_combine_operand(channel, n)) {
3944 case EggTexture::CS_unspecified:
3945 if (channel == EggTexture::CC_rgb) {
3948 return n < 2 ? TextureStage::CO_src_color : TextureStage::CO_src_alpha;
3951 return TextureStage::CO_src_alpha;
3954 case EggTexture::CO_src_color:
3955 return TextureStage::CO_src_color;
3957 case EggTexture::CO_one_minus_src_color:
3958 return TextureStage::CO_one_minus_src_color;
3960 case EggTexture::CO_src_alpha:
3961 return TextureStage::CO_src_alpha;
3963 case EggTexture::CO_one_minus_src_alpha:
3964 return TextureStage::CO_one_minus_src_alpha;
3967 return TextureStage::CO_undefined;
3976 ColorBlendAttrib::Mode EggLoader::
3977 get_color_blend_mode(EggGroup::BlendMode mode) {
3979 case EggGroup::BM_unspecified:
3980 case EggGroup::BM_none:
3981 return ColorBlendAttrib::M_none;
3982 case EggGroup::BM_add:
3983 return ColorBlendAttrib::M_add;
3984 case EggGroup::BM_subtract:
3985 return ColorBlendAttrib::M_subtract;
3986 case EggGroup::BM_inv_subtract:
3987 return ColorBlendAttrib::M_inv_subtract;
3988 case EggGroup::BM_min:
3989 return ColorBlendAttrib::M_min;
3990 case EggGroup::BM_max:
3991 return ColorBlendAttrib::M_max;
3994 return ColorBlendAttrib::M_none;
4003 ColorBlendAttrib::Operand EggLoader::
4004 get_color_blend_operand(EggGroup::BlendOperand operand) {
4006 case EggGroup::BO_zero:
4007 return ColorBlendAttrib::O_zero;
4008 case EggGroup::BO_unspecified:
4009 case EggGroup::BO_one:
4010 return ColorBlendAttrib::O_one;
4011 case EggGroup::BO_incoming_color:
4012 return ColorBlendAttrib::O_incoming_color;
4013 case EggGroup::BO_one_minus_incoming_color:
4014 return ColorBlendAttrib::O_one_minus_incoming_color;
4015 case EggGroup::BO_fbuffer_color:
4016 return ColorBlendAttrib::O_fbuffer_color;
4017 case EggGroup::BO_one_minus_fbuffer_color:
4018 return ColorBlendAttrib::O_one_minus_fbuffer_color;
4019 case EggGroup::BO_incoming_alpha:
4020 return ColorBlendAttrib::O_incoming_alpha;
4021 case EggGroup::BO_one_minus_incoming_alpha:
4022 return ColorBlendAttrib::O_one_minus_incoming_alpha;
4023 case EggGroup::BO_fbuffer_alpha:
4024 return ColorBlendAttrib::O_fbuffer_alpha;
4025 case EggGroup::BO_one_minus_fbuffer_alpha:
4026 return ColorBlendAttrib::O_one_minus_fbuffer_alpha;
4027 case EggGroup::BO_constant_color:
4028 return ColorBlendAttrib::O_constant_color;
4029 case EggGroup::BO_one_minus_constant_color:
4030 return ColorBlendAttrib::O_one_minus_constant_color;
4031 case EggGroup::BO_constant_alpha:
4032 return ColorBlendAttrib::O_constant_alpha;
4033 case EggGroup::BO_one_minus_constant_alpha:
4034 return ColorBlendAttrib::O_one_minus_constant_alpha;
4035 case EggGroup::BO_incoming_color_saturate:
4036 return ColorBlendAttrib::O_incoming_color_saturate;
4037 case EggGroup::BO_color_scale:
4038 return ColorBlendAttrib::O_color_scale;
4039 case EggGroup::BO_one_minus_color_scale:
4040 return ColorBlendAttrib::O_one_minus_color_scale;
4041 case EggGroup::BO_alpha_scale:
4042 return ColorBlendAttrib::O_alpha_scale;
4043 case EggGroup::BO_one_minus_alpha_scale:
4044 return ColorBlendAttrib::O_one_minus_alpha_scale;
4047 return ColorBlendAttrib::O_zero;
4055 bool EggLoader::VertexPoolTransform::
4056 operator < (
const EggLoader::VertexPoolTransform &other)
const {
4057 if (_vertex_pool != other._vertex_pool) {
4058 return _vertex_pool < other._vertex_pool;
4060 int compare = _transform.compare_to(other._transform, 0.001);
4065 if (_bake_in_uvs.size() != other._bake_in_uvs.size()) {
4066 return _bake_in_uvs.size() < other._bake_in_uvs.size();
4069 BakeInUVs::const_iterator ai, bi;
4070 ai = _bake_in_uvs.begin();
4071 bi = other._bake_in_uvs.begin();
4072 while (ai != _bake_in_uvs.end()) {
4073 nassertr(bi != other._bake_in_uvs.end(),
false);
4074 if ((*ai) != (*bi)) {
4075 return (*ai) < (*bi);
4080 nassertr(bi == other._bake_in_uvs.end(),
false);
A base class for any of a number of kinds of geometry primitives: polygons, point lights...
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...
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.
void set_tag(const string &key, const string &value, Thread *current_thread=Thread::get_current_thread())
Associates a user-defined value with a user-defined key which is stored on the node.
int get_num_children(Thread *current_thread=Thread::get_current_thread()) const
Returns the number of children of the referenced node.
bool parse_egg(const 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_tangible(bool tangible)
Sets the current state of the 'tangible' flag.
const Filename & get_filename() const
Returns a nonmodifiable reference to the filename.
bool has_color() const
Returns true if a blend color has been specified for the texture.
const LColor & get_border_color() const
Returns the border color if one has been specified, or (0, 0, 0, 1) otherwise.
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...
void set_vertices(const LPoint3 &v0, const LPoint3 &v1, const LPoint3 &v2, const LPoint3 &v3)
Replaces the four vertices of the occluder polygon.
This is the base class for all three-component vectors and points.
This is an iterator adaptor that converts any iterator that returns a pair (e.g.
int get_order() const
Returns the order of the curve.
This is our own Panda specialization on the default STL map.
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...
This is a 4-by-4 transform matrix.
bool has_alpha_scale() const
Returns true if an alpha_scale has been specified for the texture, false otherwise.
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...
bool has_num_views() const
Returns true if the number of views has been specified for the 3-D multiview texture, false otherwise.
This class keeps track of all the state we must make note of during the graph traversal, but cannot apply immediately.
int get_rgb_scale() const
Returns the rgb_scale value that has been specified for the texture, or 1 if no rgb_scale value has b...
This is a unit quaternion representing a rotation.
Defines a series of disconnected points.
bool is_planar() const
Returns true if all of the polygon's vertices lie within the same plane, false otherwise.
A virtual base class for parametric curves.
bool get_read_mipmaps() const
Returns the current setting of the read_mipmaps flag.
bool is_empty() const
Returns true if the NodePath contains no nodes.
CurveType get_curve_type() const
Returns the indicated type of the curve.
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...
int get_num_children(Thread *current_thread=Thread::get_current_thread()) const
Returns the number of child nodes this node has.
EggVertexPool * get_pool() const
Returns the vertex pool this vertex belongs in.
This is a two-component vector offset.
Specifies parameters that may be passed to the loader.
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, and all the things they can collide with (except geometry).
int triangulate_polygons(int flags)
Replace all higher-order polygons at this point in the scene graph and below with triangles...
int get_alpha_file_channel() const
Returns the particular channel that has been specified for the alpha-file image, or 0 if no channel h...
void set_double_sided(bool value)
If true, the back-face will also be used to occlude.
Defines a texture map that may be applied to geometry.
void apply_to_node(PandaNode *node)
Applies whatever state is appropriate to the node.
bool has_vertex_color() const
Returns true if any vertex on the primitive has a specific color set, false otherwise.
A cuboid collision volume or object.
This class is an abstraction for evaluating NURBS curves.
Defines a series of triangle fans.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
void set_format(Format format)
Changes the format value for the texture components.
PandaNode * get_child(int n, Thread *current_thread=Thread::get_current_thread()) const
Returns the nth child node of this node.
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...
void check_overall_color(bool &has_overall_color, LColor &overall_color) const
Scans the vertex pool for different colors on different vertices.
int get_num_vertices() const
Returns the number of indices used by all the primitives in this object.
const_aux_iterator aux_end() const
Returns an iterator that allows walking through the complete set of auxiliary data on the vertex...
This is the base class for all three-component vectors and points.
A base class for things which need to inherit from both TypedObject and from ReferenceCount.
A node that automatically cycles through rendering each one of its children according to its frame ra...
void set_texture_num_views(int num_views)
Specifies the expected number of views to load for the texture.
This class draws a visible representation of the NURBS curve stored in its NurbsCurveEvaluator.
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
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.
Defines a series of triangle strips.
bool has_stage_name() const
Returns true if a stage name has been explicitly specified for this texture, false otherwise...
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...
void apply_first_attribute(bool recurse)
Sets the first vertex of the triangle (or each component) to the primitive normal and/or color...
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
void set_magfilter(FilterType filter)
Sets the filtering method that should be used when viewing the texture up close.
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.
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...
int get_component_width() const
Returns the number of bytes stored for each color component of a texel.
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.
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.
double length_squared() const
Returns the square of the vector's length, cheap and easy.
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...
VertexSlider * egg_to_slider(const string &name)
Returns the VertexSlider corresponding to the indicated egg slider name.
iterator end() const
Returns an iterator that can be used to traverse through all the vertices in the pool.
void set_curve(NurbsCurveEvaluator *curve)
Sets the particular curve represented by the RopeNode.
void set_row(int row, const LVecBase4d &v)
Replaces the indicated row of the matrix.
void set_coordinate_system(CoordinateSystem coordsys)
Changes the coordinate system of the EggData.
TypedReferenceCount * get_aux_data(const string &key) const
Returns a record previously recorded via set_aux_data().
virtual bool cleanup()
Cleans up modeling errors in whatever context this makes sense.
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.
Indicates the set of TextureStages and their associated Textures that should be applied to (or remove...
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...
EggGroup * get_group_ref(int n) const
Returns the nth <Ref> entry within this group.
virtual bool determine_decal()
Walks back up the hierarchy, looking for an EggGroup at this level or above that has the "decal" flag...
bool normalize()
Normalizes the vector in place.
void set_bface_flag(bool flag)
Sets the backfacing flag of the polygon.
virtual void xform(const LMatrix4 &mat)
Transforms the contents of this PandaNode by the indicated matrix, if it means anything to do so...
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
int get_priority() const
Returns the multitexture importance value that has been specified for the texture, or 0 if no priority value has been specified.
WrapMode determine_wrap_w() const
Determines the appropriate wrap in the W direction.
const string & get_uv_name() const
Returns the texcoord name that has been specified for this texture, or the empty string if no texcoor...
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.
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.
int get_index() const
Returns the index number of the vertex within its pool.
void set_anisotropic_degree(int anisotropic_degree)
Sets the degree of anisotropic filtering for this texture.
bool has_rgb_scale() const
Returns true if an rgb_scale has been specified for the texture, false otherwise. ...
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...
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. ...
int get_num_vertices() const
Returns the number of vertices in the portal polygon.
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 ...
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.
int get_num_views() const
Returns the specified number of views specified for the 3-D multiview texture.
const string & get_stage_name() const
Returns the stage name that has been specified for this texture, or the tref name if no texture stage...
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. ...
This is a 4-by-4 transform matrix.
An instance of this class is written to the front of a Bam or Txo file to make the file a cached inst...
double get_knot(int k) const
Returns the nth knot value defined.
void set_wrap_v(WrapMode wrap)
This setting determines what happens when the texture is sampled with a V value outside the range 0...
Any one-, two-, three-, or four-component vertex, possibly with attributes such as a normal...
bool almost_equal(const LVecBase4f &other, float threshold) const
Returns true if two vectors are memberwise equal within a specified tolerance.
int get_num_knots() const
Returns the number of knots.
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 ...
const Filename & get_alpha_filename() const
Returns the separate file assigned for the alpha channel.
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.
void mesh_triangles(int flags)
Combine triangles together into triangle strips, at this group and below.
A container for geometry primitives.
bool invert_from(const LMatrix4d &other)
Computes the inverse of the other matrix, and stores the result in this matrix.
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...
void compose(const DeferredNodeProperty &other)
Composes this state with the next one encountered on a lower node during the apply traversal...
void set_alpha_mode(AlphaMode mode)
Specifies precisely how the transparency for this geometry should be achieved, or if it should be use...
void set_alpha_filename(const Filename &alpha_filename)
Sets the name of the file that contains the image's alpha channel contents.
double get_vertex_membership(const EggVertex *vert) const
Returns the amount of membership of the indicated vertex in this group.
bool almost_equal(const LVecBase3d &other, double threshold) const
Returns true if two vectors are memberwise equal within a specified tolerance.
This is the base class for all two-component vectors and points.
void set_quality_level(QualityLevel quality_level)
Sets a hint to the renderer about the desired performance / quality tradeoff for this particular text...
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...
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...
void add_data3d(double x, double y, double z)
Sets the write row to a particular 3-component value, and advances the write row. ...
const LColor & get_blend_color() const
Returns the blend color if one has been specified, or (0, 0, 0, 0) if one has not.
int find_used_textures(EggNode *node)
Walks the egg hierarchy beginning at the indicated node, looking for textures that are referenced by ...
int get_num_vertices() const
Returns the number of vertices in the occluder polygon.
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.
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...
int get_alpha_scale() const
Returns the alpha_scale value that has been specified for the texture, or 1 if no alpha_scale value h...
void set_compression(CompressionMode compression)
Requests that this particular Texture be compressed when it is loaded into texture memory...
bool get_saved_result() const
Returns the current setting of the saved_result flag.
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.
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...
const LColor & get_color() const
Returns the blend color if one has been specified, or (0, 0, 0, 1) otherwise.
Defines a series of disconnected line segments.
void local_object()
This function should be called, once, immediately after creating a new instance of some ReferenceCoun...
void set_surface(NurbsSurfaceEvaluator *surface)
Sets the particular surface represented by the SheetNode.
This is the base class for all three-component vectors and points.
void set_anisotropic_degree(int anisotropic_degree)
Specifies the level of anisotropic filtering to apply to the texture.
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
void set_wrap_u(WrapMode wrap)
This setting determines what happens when the texture is sampled with a U value outside the range 0...
void replace(iterator position, PT(EggNode) x)
Replaces the node at the indicated position with the indicated node.
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
bool has_priority() const
Returns true if a priority value for multitexture importance has been specified for the texture...
PandaNode * node() const
Returns the referenced node of the path.
Converts an EggTable hierarchy, beginning with a <Bundle> entry, into an AnimBundle hierarchy...
double length_squared() const
Returns the square of the vector's length, cheap and easy.
bool has_value() const
Returns true if this variable has an explicit value, either from a prc file or locally set...
int get_anisotropic_degree() const
Returns the anisotropic filtering degree that has been specified for this texture, or 0 if nothing has been specified.
bool has_column() const
Returns true if a valid data type has been successfully set, or false if the data type does not exist...
const Filename & get_alpha_fullpath() const
Returns the full pathname to the alpha file, if it is known; otherwise, returns the same thing as get...
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.
bool get_multiview() const
Returns the current setting of the multiview flag.
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.
int make_bins(EggGroupNode *root_group)
The main entry point to EggBinMaker.
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_border_color() const
Returns true if a border color has been specified for the texture.
bool has_dcs_type() const
Returns true if the specified DCS type is not DC_none and not DC_unspecified.
Defines a series of disconnected triangles.
void set_minfilter(FilterType filter)
Sets the filtering method that should be used when viewing the texture from a distance.
LPoint4d get_pos4() const
This is always valid, regardless of the value of get_num_dimensions.
virtual Shading get_shading() const
Returns the shading properties apparent on this particular primitive.
void reparent_decals()
For each node representing a decal base geometry (i.e.
bool has_anisotropic_degree() const
Returns true if a value for the anisotropic filtering degree has been specified for this texture...
bool set_column(int column)
Sets up the writer to use the nth data type of the GeomVertexFormat, numbering from 0...
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.
void set_color(const LColor &color)
Set the light's color...
This is our own Panda specialization on the default STL set.
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.
int get_num_components() const
Returns the number of color components for each texel of the texture image.
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, and beginning with index 0.
int add_solid(const CollisionSolid *solid)
Adds the indicated solid to the 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, for the purposes of detecting motion for accurate collision calculations.
VertexTransform * egg_to_transform(EggNode *egg_node)
Returns a JointVertexTransform suitable for applying the animation associated with the given egg node...
Converts an EggGroup hierarchy, beginning with a group with <Dart> set, to a character node with join...
void clear_vertices()
Resets the vertices of the portal to the empty list.
void set_border_color(const LColor &color)
Specifies the solid color of the texture's border.
This is a 3-by-3 transform matrix.
bool get_bface_flag() const
Retrieves the backfacing flag of the polygon.
static TextureStage * get_default()
Returns the default TextureStage that will be used for all texturing that does not name a particular ...
This is a node that contains a pointer to an AnimBundle.
This implements a solid roughly in cylindrical shape.
virtual bool is_geom_node() const
A simple downcast check.
int get_multitexture_sort() const
Returns an integer that represents the depth to which this texture is layered on all other textures i...
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.
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.
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...
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...
static LVector3f up(CoordinateSystem cs=CS_default)
Returns the up vector for the given coordinate system.
A collection of vertices.
NodePath get_child(int n, Thread *current_thread=Thread::get_current_thread()) const
Returns a NodePath representing the nth child of the referenced node.
void set_transform(const TransformState *transform, Thread *current_thread=Thread::get_current_thread())
Sets the transform that will be applied to this node and below.
bool has_uv_name() const
Returns true if a texcoord name has been explicitly specified for this texture, false otherwise...
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 set_wrap_w(WrapMode wrap)
The W wrap direction is only used for 3-d textures.
EggVertexPool * get_pool() const
Returns the vertex pool associated with the vertices of the primitive, or NULL if the primitive has n...
EggVertex * get_vertex(int index) const
Returns a particular index based on its index number.
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. ...
void set_filename(const Filename &filename)
Sets the name of the file that contains the image's contents.
const_uv_iterator uv_end() const
Returns an iterator that allows walking through the complete set of named UV's on the vertex...
int get_num_group_refs() const
Returns the number of <Ref> entries within this group.
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...
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.
int get_u_subdiv() const
Returns the requested number of subdivisions in the U direction, or 0 if no particular subdivisions h...
bool has_alpha_filename() const
Returns true if a separate file for the alpha component has been applied, false otherwise.