87 if (_data ==
nullptr) {
99 _data->add_child(_vpool);
105 if (_vpool->empty()) {
106 _data->remove_child(_vpool);
119 _data->add_child(_vpool);
122 recurse_nodes(root_path, _data,
false,
nullptr);
125 if (_vpool->empty()) {
126 _data->remove_child(_vpool);
137 bool has_decal, CharacterJointMap *joint_map) {
140 convert_geom_node(DCAST(
GeomNode, node), node_path, egg_parent, has_decal, joint_map);
142 }
else if (node->
is_of_type(LODNode::get_class_type())) {
143 convert_lod_node(DCAST(LODNode, node), node_path, egg_parent, has_decal, joint_map);
145 }
else if (node->
is_of_type(SequenceNode::get_class_type())) {
146 convert_sequence_node(DCAST(SequenceNode, node), node_path, egg_parent, has_decal, joint_map);
148 }
else if (node->
is_of_type(SwitchNode::get_class_type())) {
149 convert_switch_node(DCAST(SwitchNode, node), node_path, egg_parent, has_decal, joint_map);
151 }
else if (node->
is_of_type(CollisionNode::get_class_type())) {
152 convert_collision_node(DCAST(CollisionNode, node), node_path, egg_parent, has_decal, joint_map);
154 }
else if (node->
is_of_type(AnimBundleNode::get_class_type())) {
155 convert_anim_node(DCAST(AnimBundleNode, node), node_path, egg_parent, has_decal);
157 }
else if (node->
is_of_type(Character::get_class_type())) {
158 convert_character_node(DCAST(Character, node), node_path, egg_parent, has_decal);
162 EggGroup *egg_group =
new EggGroup(node->get_name());
164 apply_node_properties(egg_group, node);
166 recurse_nodes(node_path, egg_group, has_decal, joint_map);
176 CharacterJointMap *joint_map) {
179 EggGroup *egg_group =
new EggGroup(node->get_name());
181 apply_node_properties(egg_group, node);
186 num_children = std::min(num_children, num_switches);
188 for (
int i = 0; i < num_children; i++) {
192 PT(EggGroup) next_group =
new EggGroup;
193 convert_node(WorkingNodePath(node_path, child), next_group, has_decal, joint_map);
195 if (next_group->size() == 1) {
198 EggNode *child_node = *next_group->begin();
199 if (child_node->
is_of_type(EggGroup::get_class_type())) {
200 PT(EggGroup) child = DCAST(EggGroup, child_node);
201 next_group->remove_child(child.p());
207 PN_stdfloat in = node->
get_in(i);
208 PN_stdfloat out = node->
get_out(i);
210 EggSwitchConditionDistance dist(in, out, LCAST(
double, center));
211 next_group->set_lod(dist);
222 CharacterJointMap *joint_map) {
225 EggGroup *egg_group =
new EggGroup(node->get_name());
227 apply_node_properties(egg_group, node);
230 egg_group->set_switch_flag(
true);
231 egg_group->set_switch_fps(node->get_frame_rate());
235 for (
int i = 0; i < num_children; i++) {
239 PT(EggGroup) next_group =
new EggGroup;
240 convert_node(WorkingNodePath(node_path, child), next_group, has_decal, joint_map);
253 CharacterJointMap *joint_map) {
256 EggGroup *egg_group =
new EggGroup(node->get_name());
258 apply_node_properties(egg_group, node);
261 egg_group->set_switch_flag(
true);
265 for (
int i = 0; i < num_children; i++) {
269 PT(EggGroup) next_group =
new EggGroup;
270 convert_node(WorkingNodePath(node_path, child), next_group, has_decal, joint_map);
283 EggGroupNode *eggNode =
nullptr;
284 if (animGroup->
is_of_type(AnimBundle::get_class_type())) {
285 EggTable *eggTable =
new EggTable(animGroup->get_name());
286 eggTable ->set_table_type(EggTable::TT_bundle);
288 }
else if (animGroup->
is_of_type(AnimGroup::get_class_type())) {
289 EggTable *eggTable =
new EggTable(animGroup->get_name());
290 eggTable ->set_table_type(EggTable::TT_table);
294 if (animGroup->
is_of_type(AnimChannelMatrixXfmTable::get_class_type())) {
295 AnimChannelMatrixXfmTable *xmfTable = DCAST(AnimChannelMatrixXfmTable, animGroup);
296 EggXfmSAnim *egg_anim =
new EggXfmSAnim(
"xform");
297 egg_anim->set_fps(fps);
298 for (
int i = 0; i < num_matrix_components; i++) {
299 string componentName(1, matrix_component_letters[i]);
300 char table_id = matrix_component_letters[i];
301 CPTA_stdfloat table = xmfTable->
get_table(table_id);
304 for (
unsigned int j = 0; j < table.size(); j++) {
311 for (
int i = 0; i < num_children; i++) {
312 AnimGroup *animChild = animGroup->
get_child(i);
313 EggGroupNode *eggChildNode = convert_animGroup_node(animChild, fps);
314 if (eggChildNode!=
nullptr) {
315 nassertr(eggNode!=
nullptr,
nullptr);
331 EggTable *eggTable =
new EggTable();
333 _data->add_child(eggTable);
335 AnimBundle *animBundle = node->get_bundle();
338 EggGroupNode *eggAnimation = convert_animGroup_node(animBundle, animBundle->
get_base_frame_rate());
347convert_character_bundle(
PartGroup *bundleNode,
EggGroupNode *egg_parent, CharacterJointMap *joint_map) {
348 convert_character_bundle(bundleNode, egg_parent, joint_map,
nullptr);
357 CharacterJointMap *joint_map,
const CharacterJoint *parent_joint) {
360 const CharacterJoint *character_joint =
nullptr;
362 EggGroupNode *joint_group = egg_parent;
363 if (bundleNode->
is_of_type(CharacterJoint::get_class_type())) {
364 character_joint = DCAST(CharacterJoint, bundleNode);
366 EggGroup *joint =
new EggGroup(bundleNode->get_name());
367 joint->set_group_type(EggGroup::GT_joint);
385 LMatrix4d net_transform = invert(LCAST(
double, character_joint->_initial_net_transform_inverse));
386 if (parent_joint !=
nullptr) {
387 if (parent_joint->_initial_net_transform_inverse != character_joint->_initial_net_transform_inverse) {
388 LMatrix4d parent_inverse = LCAST(
double, parent_joint->_initial_net_transform_inverse);
389 joint->
add_matrix4(net_transform * parent_inverse);
391 }
else if (!net_transform.is_identity()) {
396 LMatrix4d default_pose = LCAST(
double, character_joint->_default_value);
398 EggTransform transform;
399 transform.
add_matrix4(LCAST(
double, default_pose));
405 if (joint_map !=
nullptr) {
406 CharacterJointMap::iterator mi = joint_map->find(character_joint);
407 if (mi != joint_map->end()) {
408 pvector<pair<EggVertex*,PN_stdfloat> > &joint_vertices = (*mi).second;
409 pvector<pair<EggVertex*,PN_stdfloat> >::const_iterator vi;
410 for (vi = joint_vertices.begin(); vi != joint_vertices.end(); ++vi) {
417 for (
int i = 0; i < num_children ; i++) {
418 PartGroup *partGroup= bundleNode->
get_child(i);
419 convert_character_bundle(partGroup, joint_group, joint_map, character_joint);
436 EggGroup *egg_group =
new EggGroup(node->get_name());
437 egg_group->set_dart_type(EggGroup::DT_structured);
439 apply_node_properties(egg_group, node);
441 CharacterJointMap joint_map;
442 recurse_nodes(node_path, egg_group, has_decal, &joint_map);
446 int num_bundles = node->get_num_bundles();
447 for (
int i = 0; i < num_bundles; ++i) {
448 PartBundle *bundle = node->get_bundle(i);
449 convert_character_bundle(bundle, egg_group, &joint_map);
460 CharacterJointMap *joint_map) {
463 EggGroup *egg_group =
new EggGroup(node->get_name());
465 apply_node_properties(egg_group, node,
false);
472 if (from_mask == into_mask) {
473 egg_group->set_collide_mask(into_mask);
475 egg_group->set_from_collide_mask(from_mask);
476 egg_group->set_into_collide_mask(into_mask);
481 egg_group->set_collide_flags(EggGroup::CF_descend);
485 LMatrix4 net_mat = net_transform->get_mat();
487 net_mat = net_mat * inv;
489 int num_solids = node->get_num_solids();
491 if (num_solids > 0) {
493 EggVertexPool *cvpool =
new EggVertexPool(
"vpool-collision");
497 for (
int i = 0; i < num_solids; i++) {
498 CPT(CollisionSolid) child = node->get_solid(i);
499 int flags = EggGroup::CF_descend;
501 if (!child->is_tangible()) {
502 flags |= EggGroup::CF_intangible;
505 if (child->has_effective_normal() &&
506 child->get_effective_normal() == LVector3::up()) {
507 flags |= EggGroup::CF_level;
510 if (child->
is_of_type(CollisionPolygon::get_class_type())) {
511 egg_group->set_cs_type(EggGroup::CST_polyset);
512 egg_group->set_collide_flags(flags);
514 EggPolygon *egg_poly =
new EggPolygon;
517 CPT(CollisionPolygon) poly = DCAST(CollisionPolygon, child);
518 int num_points = poly->get_num_points();
519 for (
int j = 0; j < num_points; j++) {
521 egg_vert.
set_pos(LCAST(
double, poly->get_point(j) * net_mat));
522 egg_vert.set_normal(LCAST(
double, poly->get_normal() * net_mat));
528 }
else if (child->
is_of_type(CollisionSphere::get_class_type())) {
529 CPT(CollisionSphere) sphere = DCAST(CollisionSphere, child);
530 LPoint3 center = sphere->get_center();
531 PN_stdfloat radius = sphere->get_radius();
533 EggGroup *egg_sphere;
534 if (num_solids == 1) {
535 egg_sphere = egg_group;
537 egg_sphere =
new EggGroup;
541 if (child->
is_of_type(CollisionInvSphere::get_class_type())) {
542 egg_sphere->set_cs_type(EggGroup::CST_inv_sphere);
544 egg_sphere->set_cs_type(EggGroup::CST_sphere);
546 egg_sphere->set_collide_flags(flags);
548 EggVertex ev1, ev2, ev3, ev4;
549 ev1.
set_pos(LCAST(
double, (center + LVector3(radius, 0, 0)) * net_mat));
550 ev2.
set_pos(LCAST(
double, (center + LVector3(0, radius, 0)) * net_mat));
551 ev3.
set_pos(LCAST(
double, (center + LVector3(-radius, 0, 0)) * net_mat));
552 ev4.
set_pos(LCAST(
double, (center + LVector3(0, -radius, 0)) * net_mat));
554 EggPolygon *egg_poly =
new EggPolygon;
562 }
else if (child->
is_of_type(CollisionPlane::get_class_type())) {
563 LPlane plane = DCAST(CollisionPlane, child)->get_plane();
564 LPoint3 origin = plane.get_point();
565 LVector3 normal = plane.get_normal();
570 if (std::fabs(normal[2]) > std::fabs(normal[1])) {
571 vec1 = normal.cross(LVector3(0, 1, 0));
573 vec1 = normal.cross(LVector3(0, 0, 1));
577 LVector3 vec2 = normal.cross(vec1);
580 if (num_solids == 1) {
581 egg_plane = egg_group;
583 egg_plane =
new EggGroup;
586 egg_plane->set_cs_type(EggGroup::CST_plane);
587 egg_plane->set_collide_flags(flags);
589 EggVertex ev0, ev1, ev2;
590 ev0.
set_pos(LCAST(
double, origin * net_mat));
591 ev1.
set_pos(LCAST(
double, (origin + vec1) * net_mat));
592 ev2.
set_pos(LCAST(
double, (origin + vec2) * net_mat));
594 EggPolygon *egg_poly =
new EggPolygon;
601 }
else if (child->
is_of_type(CollisionBox::get_class_type())) {
602 CPT(CollisionBox) box = DCAST(CollisionBox, child);
603 LPoint3 min_point = box->get_min();
604 LPoint3 max_point = box->get_max();
607 if (num_solids == 1) {
610 egg_box =
new EggGroup;
613 egg_box->set_cs_type(EggGroup::CST_box);
614 egg_box->set_collide_flags(flags);
618 ev0.
set_pos(LCAST(
double, min_point * net_mat));
619 ev1.
set_pos(LCAST(
double, max_point * net_mat));
621 EggLine *egg_poly =
new EggLine;
627 }
else if (child->
is_of_type(CollisionCapsule::get_class_type())) {
628 CPT(CollisionCapsule) capsule = DCAST(CollisionCapsule, child);
629 LPoint3 point_a = capsule->get_point_a();
630 LPoint3 point_b = capsule->get_point_b();
631 LPoint3 centroid = (point_a + point_b) * 0.5f;
634 LVector3 axis = point_b - point_a;
636 if (std::fabs(axis[2]) > std::fabs(axis[1])) {
637 sideways = axis.cross(LVector3(0, 1, 0));
639 sideways = axis.cross(LVector3(0, 0, 1));
641 sideways.normalize();
642 sideways *= capsule->get_radius();
643 LVector3 extend = axis.normalized() * capsule->get_radius();
645 EggGroup *egg_capsule;
646 if (num_solids == 1) {
647 egg_capsule = egg_group;
649 egg_capsule =
new EggGroup;
652 egg_capsule->set_cs_type(EggGroup::CST_tube);
653 egg_capsule->set_collide_flags(flags);
657 EggVertex ev0, ev1, ev2, ev3;
658 ev0.
set_pos(LCAST(
double, (point_a - extend) * net_mat));
659 ev1.
set_pos(LCAST(
double, (centroid + sideways) * net_mat));
660 ev2.
set_pos(LCAST(
double, (point_b + extend) * net_mat));
661 ev3.
set_pos(LCAST(
double, (centroid - sideways) * net_mat));
663 EggPolygon *egg_poly =
new EggPolygon;
672 nout <<
"Encountered unknown collision solid type " << child->get_type() <<
"\n";
678 recurse_nodes(node_path, egg_group, has_decal, joint_map);
686 EggGroupNode *egg_parent,
bool has_decal, CharacterJointMap *joint_map) {
687 PT(EggGroup) egg_group =
new EggGroup(node->get_name());
688 bool fancy_attributes = apply_node_properties(egg_group, node);
690 if (node->get_effects()->has_decal()) {
695 egg_group->set_decal_flag(
true);
698 if (fancy_attributes || has_decal || !node->get_name().empty()) {
703 egg_parent = egg_group;
707 CPT(RenderState) net_state = np.get_net_state();
709 LMatrix4 net_mat = net_transform->get_mat();
711 net_mat = net_mat * inv;
715 for (
int i = 0; i < num_geoms; ++i) {
717 CPT(RenderState) geom_net_state = net_state->compose(geom_state);
722 if (num_geoms == 1 && node->
get_num_children() == 0 && egg_parent == egg_group &&
723 !geom_state->is_empty() && node->get_state()->is_empty()) {
724 apply_state_properties(egg_group, geom_state);
725 geom_state = RenderState::make_empty();
728 const Geom *geom = node->get_geom(i);
729 int num_primitives = geom->get_num_primitives();
730 for (
int j = 0; j < num_primitives; ++j) {
731 const GeomPrimitive *primitive = geom->get_primitive(j);
732 CPT(GeomPrimitive) simple = primitive->
decompose();
733 CPT(GeomVertexData) vdata = geom->get_vertex_data();
735 convert_primitive(vdata, simple, geom_state, geom_net_state,
736 net_mat, egg_parent, joint_map);
740 recurse_nodes(node_path, egg_parent, has_decal, joint_map);
751 CharacterJointMap *joint_map) {
752 GeomVertexReader reader(vertex_data);
753 const GeomVertexFormat *format = vertex_data->
get_format();
756 PT(EggPrimitive) egg_prim;
757 if (primitive->
is_of_type(GeomTriangles::get_class_type())) {
758 egg_prim =
new EggPolygon();
759 }
else if (primitive->
is_of_type(GeomPatches::get_class_type())) {
760 egg_prim =
new EggPatch();
761 }
else if (primitive->
is_of_type(GeomPoints::get_class_type())) {
762 egg_prim =
new EggPoint();
763 }
else if (primitive->
is_of_type(GeomLines::get_class_type())) {
764 egg_prim =
new EggLine();
771 apply_state_properties(egg_prim, geom_state);
774 LVecBase4 color_scale(1.0f, 1.0f, 1.0f, 1.0f);
775 const ColorScaleAttrib *csa;
776 if (net_state->get_attrib(csa)) {
781 bool has_color_override =
false;
782 bool has_color_off =
false;
783 LColor color_override;
784 const ColorAttrib *ca;
785 if (net_state->get_attrib(ca)) {
787 has_color_override =
true;
789 color_override.set(color_override[0] * color_scale[0],
790 color_override[1] * color_scale[1],
791 color_override[2] * color_scale[2],
792 color_override[3] * color_scale[3]);
795 has_color_off =
true;
800 EggMaterial *egg_mat =
nullptr;
801 const MaterialAttrib *ma;
802 if (net_state->get_attrib(ma)) {
804 if (egg_mat !=
nullptr) {
805 egg_prim->set_material(egg_mat);
810 const TextureAttrib *ta;
811 if (net_state->get_attrib(ta)) {
815 EggTexture *egg_tex = get_egg_texture(ta->
get_on_texture(tex_stage));
816 if (egg_tex !=
nullptr) {
818 case TextureStage::M_modulate:
819 if (has_color_off ==
true && i == 0) {
820 egg_tex->set_env_type(EggTexture::ET_replace);
822 egg_tex->set_env_type(EggTexture::ET_modulate);
825 case TextureStage::M_decal:
826 egg_tex->set_env_type(EggTexture::ET_decal);
828 case TextureStage::M_blend:
829 egg_tex->set_env_type(EggTexture::ET_blend);
831 case TextureStage::M_replace:
832 egg_tex->set_env_type(EggTexture::ET_replace);
834 case TextureStage::M_add:
835 egg_tex->set_env_type(EggTexture::ET_add);
837 case TextureStage::M_blend_color_scale:
838 egg_tex->set_env_type(EggTexture::ET_blend_color_scale);
840 case TextureStage::M_modulate_glow:
841 egg_tex->set_env_type(EggTexture::ET_modulate_glow);
843 case TextureStage::M_modulate_gloss:
844 egg_tex->set_env_type(EggTexture::ET_modulate_gloss);
846 case TextureStage::M_normal:
847 egg_tex->set_env_type(EggTexture::ET_normal);
849 case TextureStage::M_normal_height:
850 egg_tex->set_env_type(EggTexture::ET_normal_height);
852 case TextureStage::M_glow:
853 egg_tex->set_env_type(EggTexture::ET_glow);
855 case TextureStage::M_gloss:
856 egg_tex->set_env_type(EggTexture::ET_gloss);
858 case TextureStage::M_height:
859 egg_tex->set_env_type(EggTexture::ET_height);
861 case TextureStage::M_selector:
862 egg_tex->set_env_type(EggTexture::ET_selector);
864 case TextureStage::M_normal_gloss:
865 egg_tex->set_env_type(EggTexture::ET_normal_gloss);
867 case TextureStage::M_emission:
868 egg_tex->set_env_type(EggTexture::ET_emission);
875 if (name !=
nullptr && name != InternalName::get_texcoord()) {
879 egg_prim->add_texture(egg_tex);
885 const CullFaceAttrib *cfa;
886 if (net_state->get_attrib(cfa)) {
888 egg_prim->set_bface_flag(
true);
893 const RenderModeAttrib *rma;
894 if (net_state->get_attrib(rma)) {
895 if (egg_prim->is_of_type(EggPoint::get_class_type())) {
896 EggPoint *egg_point = (EggPoint *)egg_prim.p();
900 }
else if (egg_prim->is_of_type(EggLine::get_class_type())) {
901 EggLine *egg_line = (EggLine *)egg_prim.p();
906 CPT(TransformBlendTable) transformBlendTable = vertex_data->get_transform_blend_table();
911 for (
int i = 0; i < num_primitives; ++i) {
912 PT(EggPrimitive) egg_child = egg_prim->make_copy();
915 for (
int j = 0; j < num_vertices; j++) {
919 reader.set_row(primitive->
get_vertex(i * num_vertices + j));
921 reader.set_column(InternalName::get_vertex());
922 LVertex vertex = reader.get_data3();
923 egg_vert.
set_pos(LCAST(
double, vertex * net_mat));
925 if (vertex_data->
has_column(InternalName::get_normal())) {
926 reader.set_column(InternalName::get_normal());
927 LNormal normal = reader.get_data3();
928 egg_vert.set_normal(LCAST(
double, normal * net_mat));
930 if (has_color_override) {
931 egg_vert.set_color(color_override);
933 }
else if (!has_color_off) {
934 LColor color(1.0f, 1.0f, 1.0f, 1.0f);
935 if (vertex_data->
has_column(InternalName::get_color())) {
936 reader.set_column(InternalName::get_color());
937 color = reader.get_data4();
939 egg_vert.set_color(LColor(color[0] * color_scale[0],
940 color[1] * color_scale[1],
941 color[2] * color_scale[2],
942 color[3] * color_scale[3]));
946 const InternalName *texcoord_name = format->
get_texcoord(ti);
947 reader.set_column(texcoord_name);
948 LTexCoord uv = reader.get_data2();
949 if (texcoord_name == InternalName::get_texcoord()) {
950 egg_vert.
set_uv(LCAST(
double, uv));
956 EggVertex *new_egg_vert = _vpool->create_unique_vertex(egg_vert);
958 if (vertex_data->
has_column(InternalName::get_transform_blend()) &&
959 joint_map !=
nullptr && transformBlendTable !=
nullptr) {
960 reader.set_column(InternalName::get_transform_blend());
961 int idx = reader.get_data1i();
962 const TransformBlend &blend = transformBlendTable->get_blend(idx);
964 for (
int k = 0; k < num_weights; ++k) {
967 const VertexTransform *vertex_transform = blend.
get_transform(k);
968 if (vertex_transform->
is_of_type(JointVertexTransform::get_class_type())) {
969 const JointVertexTransform *joint_vertex_transform = DCAST(
const JointVertexTransform, vertex_transform);
971 CharacterJointMap::iterator mi = joint_map->find(joint_vertex_transform->
get_joint());
972 if (mi == joint_map->end()) {
973 mi = joint_map->insert(CharacterJointMap::value_type(joint_vertex_transform->
get_joint(), pvector<pair<EggVertex*,PN_stdfloat> >())).first;
975 pvector<pair<EggVertex*,PN_stdfloat> > &joint_vertices = (*mi).second;
976 joint_vertices.push_back(pair<EggVertex*,PN_stdfloat>(new_egg_vert, weight));
982 egg_child->add_vertex(new_egg_vert);
992 bool has_decal, CharacterJointMap *joint_map) {
993 PandaNode *node = node_path.
node();
996 for (
int i = 0; i < num_children; i++) {
998 convert_node(WorkingNodePath(node_path, child), egg_parent, has_decal, joint_map);
1007apply_node_properties(
EggGroup *egg_group,
PandaNode *node,
bool allow_backstage) {
1008 bool any_applied =
false;
1014 egg_group->add_object_type(
"backstage");
1017 if (node->has_tags()) {
1018 if (apply_tags(egg_group, node)) {
1023 if (node->
is_of_type(ModelNode::get_class_type())) {
1024 ModelNode *model_node = DCAST(ModelNode, node);
1026 case ModelNode::PT_none:
1027 egg_group->set_model_flag(
true);
1030 case ModelNode::PT_drop_node:
1033 case ModelNode::PT_net:
1034 egg_group->set_dcs_type(EggGroup::DC_net);
1037 case ModelNode::PT_local:
1038 egg_group->set_dcs_type(EggGroup::DC_local);
1041 case ModelNode::PT_no_touch:
1042 egg_group->set_dcs_type(EggGroup::DC_no_touch);
1047 if (node->
is_of_type(UvScrollNode::get_class_type())) {
1048 const UvScrollNode *scroll_node = (
const UvScrollNode *)node;
1049 egg_group->set_scroll_u(scroll_node->get_u_speed());
1050 egg_group->set_scroll_v(scroll_node->get_v_speed());
1051 egg_group->set_scroll_w(scroll_node->get_w_speed());
1052 egg_group->set_scroll_r(scroll_node->get_r_speed());
1055 const RenderEffects *effects = node->get_effects();
1056 const RenderEffect *effect = effects->
get_effect(BillboardEffect::get_class_type());
1057 if (effect !=
nullptr) {
1058 const BillboardEffect *bbe = DCAST(BillboardEffect, effect);
1060 egg_group->set_billboard_type(EggGroup::BT_axis);
1064 egg_group->set_billboard_type(EggGroup::BT_point_camera_relative);
1068 egg_group->set_billboard_type(EggGroup::BT_point_world_relative);
1078 const LVecBase3 &scale = transform->
get_scale();
1079 const LQuaternion &quat = transform->
get_quat();
1080 const LVecBase3 &pos = transform->
get_pos();
1081 if (!scale.almost_equal(LVecBase3(1.0f, 1.0f, 1.0f))) {
1084 if (!quat.is_identity()) {
1087 if (!pos.almost_equal(LVecBase3::zero())) {
1091 }
else if (transform->
has_mat()) {
1093 const LMatrix4 &mat = transform->
get_mat();
1099 const RenderState *state = node->get_state();
1100 if (apply_state_properties(egg_group, state)) {
1117 bool any_applied =
false;
1120 const TransparencyAttrib *tra;
1121 if (state->get_attrib(tra)) {
1122 EggRenderMode::AlphaMode tex_trans = EggRenderMode::AM_unspecified;
1124 case TransparencyAttrib::M_none:
1125 tex_trans = EggRenderMode::AM_off;
1127 case TransparencyAttrib::M_alpha:
1128 tex_trans = EggRenderMode::AM_blend;
1130 case TransparencyAttrib::M_premultiplied_alpha:
1131 tex_trans = EggRenderMode::AM_premultiplied;
1133 case TransparencyAttrib::M_multisample:
1134 tex_trans = EggRenderMode::AM_ms;
1136 case TransparencyAttrib::M_multisample_mask:
1137 tex_trans = EggRenderMode::AM_ms_mask;
1139 case TransparencyAttrib::M_binary:
1140 tex_trans = EggRenderMode::AM_binary;
1142 case TransparencyAttrib::M_dual:
1143 tex_trans = EggRenderMode::AM_dual;
1151 const DepthWriteAttrib *dwa;
1152 if (state->get_attrib(dwa)) {
1153 if (dwa->
get_mode() != DepthWriteAttrib::M_off) {
1156 }
else if (egg_render_mode->
get_alpha_mode() == EggRenderMode::AM_blend) {
1158 egg_render_mode->
set_alpha_mode(EggRenderMode::AM_blend_no_occlude);
1166 const DepthTestAttrib *dta;
1167 if (state->get_attrib(dta)) {
1168 RenderAttrib::PandaCompareFunc mode = dta->
get_mode();
1169 if (mode == DepthTestAttrib::M_none || mode == DepthTestAttrib::M_always) {
1177 const DepthOffsetAttrib *doa;
1178 if (state->get_attrib(doa)) {
1183 const CullBinAttrib *cba;
1184 if (state->get_attrib(cba)) {
1199 bool any_applied =
false;
1204 for (
size_t i = 0; i < keys.size(); ++i) {
1205 if (apply_tag(egg_group, node, keys[i])) {
1217 if (!node->has_tag(tag)) {
1221 string value = node->get_tag(tag);
1222 egg_group->
set_tag(tag, value);
1231 if (mat !=
nullptr) {
1232 EggMaterial temp(mat->get_name());
1233 if (mat->has_base_color()) {
1234 temp.set_base(mat->get_base_color());
1237 if (mat->has_ambient()) {
1238 temp.set_amb(mat->get_ambient());
1241 if (mat->has_diffuse()) {
1242 temp.set_diff(mat->get_diffuse());
1245 if (mat->has_specular()) {
1246 temp.set_spec(mat->get_specular());
1249 if (mat->has_emission()) {
1250 temp.set_emit(mat->get_emission());
1253 if (mat->has_roughness()) {
1254 temp.set_roughness(mat->get_roughness());
1256 temp.set_shininess(mat->get_shininess());
1259 if (mat->has_metallic()) {
1260 temp.set_metallic(mat->get_metallic());
1263 if (mat->has_refractive_index()) {
1264 temp.set_ior(mat->get_refractive_index());
1267 temp.set_local(mat->get_local());
1269 return _materials.create_unique_material(temp, ~EggMaterial::E_mref_name);
1279get_egg_texture(
Texture *tex) {
1280 if (tex !=
nullptr) {
1286 temp.set_alpha_filename(alpha);
1290 case SamplerState::FT_nearest:
1291 temp.set_minfilter(EggTexture::FT_nearest);
1293 case SamplerState::FT_linear:
1294 temp.set_minfilter(EggTexture::FT_linear);
1296 case SamplerState::FT_nearest_mipmap_nearest:
1297 temp.set_minfilter(EggTexture::FT_nearest_mipmap_nearest);
1299 case SamplerState::FT_linear_mipmap_nearest:
1300 temp.set_minfilter(EggTexture::FT_linear_mipmap_nearest);
1302 case SamplerState::FT_nearest_mipmap_linear:
1303 temp.set_minfilter(EggTexture::FT_nearest_mipmap_linear);
1305 case SamplerState::FT_linear_mipmap_linear:
1306 temp.set_minfilter(EggTexture::FT_linear_mipmap_linear);
1314 case SamplerState::FT_nearest:
1315 temp.set_magfilter(EggTexture::FT_nearest);
1317 case SamplerState::FT_linear:
1318 temp.set_magfilter(EggTexture::FT_linear);
1326 case SamplerState::WM_clamp:
1327 temp.set_wrap_u(EggTexture::WM_clamp);
1329 case SamplerState::WM_repeat:
1330 temp.set_wrap_u(EggTexture::WM_repeat);
1340 case SamplerState::WM_clamp:
1341 temp.set_wrap_v(EggTexture::WM_clamp);
1343 case SamplerState::WM_repeat:
1344 temp.set_wrap_v(EggTexture::WM_repeat);
1354 case Texture::F_red:
1355 temp.set_format(EggTexture::F_red);
1357 case Texture::F_green:
1358 temp.set_format(EggTexture::F_green);
1360 case Texture::F_blue:
1361 temp.set_format(EggTexture::F_blue);
1363 case Texture::F_alpha:
1364 temp.set_format(EggTexture::F_alpha);
1366 case Texture::F_rgb:
1367 temp.set_format(EggTexture::F_rgb);
1369 case Texture::F_rgb5:
1370 temp.set_format(EggTexture::F_rgb5);
1372 case Texture::F_rgb8:
1373 temp.set_format(EggTexture::F_rgb8);
1375 case Texture::F_rgb12:
1376 temp.set_format(EggTexture::F_rgb12);
1378 case Texture::F_rgb332:
1379 temp.set_format(EggTexture::F_rgb332);
1381 case Texture::F_rgba:
1382 temp.set_format(EggTexture::F_rgba);
1384 case Texture::F_rgbm:
1385 temp.set_format(EggTexture::F_rgbm);
1387 case Texture::F_rgba4:
1388 temp.set_format(EggTexture::F_rgba4);
1390 case Texture::F_rgba5:
1391 temp.set_format(EggTexture::F_rgba5);
1393 case Texture::F_rgba8:
1394 temp.set_format(EggTexture::F_rgba8);
1396 case Texture::F_rgba12:
1397 temp.set_format(EggTexture::F_rgba12);
1399 case Texture::F_luminance:
1400 temp.set_format(EggTexture::F_luminance);
1402 case Texture::F_luminance_alpha:
1403 temp.set_format(EggTexture::F_luminance_alpha);
1405 case Texture::F_luminance_alphamask:
1406 temp.set_format(EggTexture::F_luminance_alphamask);
1408 case Texture::F_srgb:
1409 temp.set_format(EggTexture::F_srgb);
1411 case Texture::F_srgb_alpha:
1412 temp.set_format(EggTexture::F_srgb_alpha);
1418 return _textures.create_unique_texture(temp, ~EggTexture::E_tref_name);
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is a node that contains a pointer to an AnimBundle.
get_base_frame_rate
Returns the ideal number of frames per second of the animation, when it is running at normal speed.
has_table
Returns true if the indicated subtable has been assigned.
get_table
Returns a pointer to the indicated subtable's data, if it exists, or NULL if it does not.
This is the base class for AnimChannel and AnimBundle.
get_child
Returns the nth child of the group.
get_num_children
Returns the number of child nodes of the group.
bool get_eye_relative() const
Returns true if this billboard interprets the up vector relative to the camera, or false if it is rel...
bool get_axial_rotate() const
Returns true if this billboard rotates only around the axis of the up vector, or false if it rotates ...
This represents one joint of the character's animation, containing an animating transform matrix.
An animated character, with skeleton-morph animation and either soft- skinned or hard-skinned vertice...
A node in the scene graph that can hold any number of CollisionSolids.
get_into_collide_mask
Returns the current "into" CollideMask.
get_from_collide_mask
Returns the current "from" CollideMask.
get_default_collide_mask
Returns the default into_collide_mask assigned to new CollisionNodes.
get_color
If the type is T_flat or T_off, this returns the color that will be applied to geometry.
get_color_type
Returns the type of color specified by this ColorAttrib.
get_scale
Returns the scale to be applied to colors.
get_draw_order
Returns the draw order this attribute specifies.
get_bin_name
Returns the name of the bin this attribute specifies.
get_effective_mode
Returns the effective culling mode.
get_offset
Returns the depth offset represented by this attrib.
get_mode
Returns the depth write mode.
get_mode
Returns the depth write mode.
This is the primary interface into all the egg data, and the root of the egg file structure.
A base class for nodes in the hierarchy that are not leaf nodes.
EggNode * add_child(EggNode *node)
Adds the indicated child to the group and returns it.
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
void set_vertex_membership(EggVertex *vert, double membership)
Explicitly sets the net membership of the indicated vertex in this group to the given value.
void set_tag(const std::string &key, const std::string &value)
Associates a user-defined value with a user-defined key which is stored on the node.
set_default_pose
Replaces the initial pose transform.
const LMatrix4d & get_vertex_frame_inv() const
Returns the inverse of the matrix returned by get_vertex_frame().
EggVertex * add_vertex(EggVertex *vertex)
Adds the indicated vertex to the end of the primitive's list of vertices, and returns it.
This class stores miscellaneous rendering properties that is associated with geometry,...
void set_draw_order(int order)
Sets the "draw-order" flag associated with this object.
void set_depth_write_mode(DepthWriteMode mode)
Specifies whether writes should be made to the depth buffer (assuming the rendering backend provides ...
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_depth_test_mode(DepthTestMode mode)
Specifies whether this geometry should be tested against the depth buffer when it is drawn (assuming ...
void set_bin(const std::string &bin)
Sets the "bin" string for this particular object.
AlphaMode get_alpha_mode() const
Returns the alpha mode that was set, or AM_unspecified if nothing was set.
void set_depth_offset(int bias)
Sets the "depth-offset" flag associated with this object.
void add_node(PandaNode *node)
Adds the scene graph rooted at the indicated node to the accumulated egg data within this object.
void add_subgraph(PandaNode *root)
Adds the scene graph rooted at the indicated node (but without the node itself) to the accumulated eg...
Defines a texture map that may be applied to geometry.
set_uv_name
Specifies the named set of texture coordinates that this texture will use when it is applied to geome...
A collection of vertices.
EggVertex * create_unique_vertex(const EggVertex ©)
Creates a new vertex in the pool that is a copy of the indicated one and returns it.
void set_pos(double pos)
Sets the vertex position.
void set_uv(const LTexCoordd &texCoord)
Replaces the unnamed UV coordinate pair on the vertex with the indicated value.
void add_component_data(const std::string &component_name, double value)
Adds a new row to the named component (one of matrix_component_letters) of the table.
std::string get_basename_wo_extension() const
Returns the basename part of the filename, without the file extension.
A node that holds Geom objects, renderable pieces of geometry.
get_num_geoms
Returns the number of geoms in the node.
get_geom_state
Returns the RenderState associated with the nth geom of the node.
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
int get_num_primitives() const
Returns the number of individual primitives stored within this object.
get_vertex
Returns the ith vertex index in the table.
ConstPointerTo< GeomPrimitive > decompose() const
Decomposes a complex primitive type into a simpler primitive type, for instance triangle strips to tr...
get_num_vertices_per_primitive
If the primitive type is a simple type in which all primitives have the same number of vertices,...
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
bool has_column(const InternalName *name) const
Returns true if the data has the named column, false otherwise.
get_format
Returns a pointer to the GeomVertexFormat structure that defines this data.
get_basename
Return the name represented by just this particular InternalName object, ignoring its parents names.
get_out
Returns the "out" distance of the indicated switch range.
get_in
Returns the "in" distance of the indicated switch range.
get_center
Returns the center of the LOD.
get_num_switches
Returns the number of switch ranges added to the LODNode.
get_material
If the MaterialAttrib is not an 'off' MaterialAttrib, returns the material that is associated.
Defines the way an object appears in the presence of lighting.
PreserveTransform get_preserve_transform() const
Returns the current setting of the preserve_transform flag.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
A basic node of the scene graph or data graph.
virtual bool is_geom_node() const
A simple downcast check.
void get_tag_keys(vector_string &keys) const
Fills the given vector up with the list of tags on this PandaNode.
is_overall_hidden
Returns true if the node has been hidden to all cameras by clearing its overall bit.
get_child
Returns the nth child node of this node.
get_num_children
Returns the number of child nodes this node has.
This is the base class for PartRoot and MovingPart.
get_num_children
Returns the number of child nodes of the group.
get_child
Returns the nth child of the group.
const RenderEffect * get_effect(size_t n) const
Returns the nth effect in the state.
get_perspective
Returns the perspective flag.
get_thickness
Returns the line width or point thickness.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
bool is_empty() const
Returns true if the state is empty, false otherwise.
A node that automatically cycles through rendering each one of its children according to its frame ra...
A node that renders only one of its children, according to the user's indication.
get_num_on_stages
Returns the number of stages that are turned on by the attribute.
get_on_texture
Returns the texture associated with the indicated stage, or NULL if no texture is associated.
get_on_stage
Returns the nth stage turned on by the attribute, sorted in render order.
get_mode
Return the mode of this stage.
get_texcoord_name
See set_texcoord_name.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
get_format
Returns the format of the texture, which represents both the semantic meaning of the texels and,...
get_minfilter
Returns the filter mode of the texture for minification.
has_filename
Returns true if the filename has been set and is available.
get_filename
Returns the filename that has been set.
get_alpha_filename
Returns the alpha_filename that has been set.
get_magfilter
Returns the filter mode of the texture for magnification.
has_alpha_filename
Returns true if the alpha_filename has been set and is available.
get_wrap_u
Returns the wrap mode of the texture in the U direction.
get_wrap_v
Returns the wrap mode of the texture in the V direction.
get_mode
Returns the transparency mode.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
This is a class designed to support low-overhead traversals of the complete scene graph,...
PandaNode * node() const
Returns the node traversed to so far.
get_node_path
Constructs and returns an actual NodePath that represents the same path we have just traversed.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.