31#include <FCDocument/FCDAsset.h>
32#include <FCDocument/FCDocumentTools.h>
33#include <FCDocument/FCDSceneNode.h>
34#include <FCDocument/FCDSceneNodeTools.h>
35#include <FCDocument/FCDGeometry.h>
36#include <FCDocument/FCDGeometryInstance.h>
37#include <FCDocument/FCDGeometryPolygons.h>
38#include <FCDocument/FCDGeometrySource.h>
39#include <FCDocument/FCDSkinController.h>
40#include <FCDocument/FCDController.h>
41#include <FCDocument/FCDControllerInstance.h>
42#include <FCDocument/FCDMorphController.h>
43#include <FCDocument/FCDMaterialInstance.h>
44#include <FCDocument/FCDExtra.h>
45#include <FCDocument/FCDEffect.h>
46#include <FCDocument/FCDEffectStandard.h>
47#if FCOLLADA_VERSION >= 0x00030005
48 #include <FCDocument/FCDGeometryPolygonsInput.h>
63 _error_handler =
nullptr;
64 _invert_transparency =
false;
81 if (_error_handler !=
nullptr) {
82 delete _error_handler;
91 return new DAEToEggConverter(*
this);
120 if (_error_handler ==
nullptr) {
121 _error_handler =
new FUErrorSimpleHandler;
125 if (_egg_data->get_coordinate_system() == CS_default) {
126 _egg_data->set_coordinate_system(CS_yup_right);
130 FCollada::Initialize();
131 _document = FCollada::LoadDocument(filename.to_os_specific().c_str());
132 if (_document ==
nullptr) {
133 daeegg_cat.error() <<
"Failed to load document: " << _error_handler->GetErrorString() << endl;
138 if (_document->GetAsset() !=
nullptr) {
139 FCDocumentTools::StandardizeUpAxisAndLength(_document);
145 string model_name = _character_name;
147 FCDSceneNode* visual_scene = _document->GetVisualSceneInstance();
148 if (visual_scene !=
nullptr) {
149 if (model_name.empty()) {
151 model_name = FROM_FSTRING(visual_scene->GetName());
153 scene_group =
new EggGroup(model_name);
154 _egg_data->add_child(scene_group);
156 for (
size_t ch = 0; ch < visual_scene->GetChildrenCount(); ++ch) {
157 process_node(scene_group, visual_scene->GetChild(ch));
161 <<
"No visual scene instance found in COLLADA document.\n";
167 Characters::iterator it;
168 DaeCharacter *character;
169 for (it = _characters.begin(); it != _characters.end(); ++it) {
174 const FCDGeometryMesh *mesh = character->_skin_mesh;
176 if (mesh !=
nullptr) {
178 daeegg_cat.spam() <<
"Processing mesh for controller\n";
179 process_mesh(character->_node_group, mesh, materials, character);
185 for (
size_t ch = 0; ch < visual_scene->GetChildrenCount(); ++ch) {
186 character->
adjust_joints(visual_scene->GetChild(ch), _joints, LMatrix4d::ident_mat());
189 if (scene_group !=
nullptr) {
192 _egg_data->remove_child(scene_group);
194 scene_group->set_dart_type(EggGroup::DT_default);
200 _table->set_table_type(EggTable::TT_table);
201 _egg_data->add_child(_table);
204 bundle->set_table_type(EggTable::TT_bundle);
205 _table->add_child(bundle);
208 skeleton->set_table_type(EggTable::TT_table);
209 bundle->add_child(skeleton);
213 Characters::iterator it;
214 DaeCharacter *character;
215 for (it = _characters.begin(); it != _characters.end(); ++it) {
225 if (_frame_inc != 0.0) {
229 if (_end_frame != _start_frame) {
230 start = _start_frame;
234 start = *keys.begin();
235 end = *keys.rbegin();
239 for (
float t = start; t <= end; t += _frame_inc) {
246 if (_end_frame != 0.0) {
248 float end = _end_frame;
249 pset<float>::iterator ki;
250 for (ki = keys.begin(); ki != keys.end(); ++ki) {
251 if (*ki > end && !IS_THRESHOLD_EQUAL(*ki, end, 0.001)) {
252 keys.erase(ki, keys.end());
257 if (_start_frame != 0.0) {
259 float start = _start_frame;
260 pset<float>::iterator ki;
261 for (ki = keys.begin(); ki != keys.end(); ++ki) {
262 if (*ki > start && !IS_THRESHOLD_EQUAL(*ki, start, 0.001)) {
263 keys.erase(keys.begin(), ki);
271 pset<float>::const_iterator ki = keys.begin();
272 if (ki != keys.end()) {
276 for (++ki; ki != keys.end(); ++ki) {
277 if (diff != 0 && !IS_THRESHOLD_EQUAL((*ki - last), diff, 0.001)) {
279 <<
"This does not appear to be a sampled animation.\n"
280 <<
"Specify the -sf, -ef and -if options to indicate how the "
281 <<
"animations should be sampled.\n";
292 for (
size_t ch = 0; ch < visual_scene->GetChildrenCount(); ++ch) {
293 character->
build_table(skeleton, visual_scene->GetChild(ch), keys);
299 SAFE_DELETE(visual_scene);
300 SAFE_DELETE(_document);
313 if (IS_NEARLY_EQUAL(_unit_meters, 0.001)) {
314 return DU_millimeters;
316 if (IS_NEARLY_EQUAL(_unit_meters, 0.01)) {
317 return DU_centimeters;
319 if (IS_NEARLY_EQUAL(_unit_meters, 1.0)) {
322 if (IS_NEARLY_EQUAL(_unit_meters, 1000.0)) {
323 return DU_kilometers;
325 if (IS_NEARLY_EQUAL(_unit_meters, 3.0 * 12.0 * 0.0254)) {
328 if (IS_NEARLY_EQUAL(_unit_meters, 12.0 * 0.0254)) {
331 if (IS_NEARLY_EQUAL(_unit_meters, 0.0254)) {
334 if (IS_NEARLY_EQUAL(_unit_meters, 1852.0)) {
335 return DU_nautical_miles;
337 if (IS_NEARLY_EQUAL(_unit_meters, 5280.0 * 12.0 * 0.0254)) {
338 return DU_statute_miles;
345void DAEToEggConverter::
347 const FCDAsset *asset = _document->GetAsset();
348 if (_document->GetAsset() ==
nullptr) {
352 _unit_name = FROM_FSTRING(asset->GetUnitName());
353 _unit_meters = asset->GetUnitConversionFactor();
356 FMVector3 up_axis = asset->GetUpAxis();
358 if (up_axis == FMVector3(0, 1, 0)) {
359 _egg_data->set_coordinate_system(CS_yup_right);
361 }
else if (up_axis == FMVector3(0, 0, 1)) {
362 _egg_data->set_coordinate_system(CS_zup_right);
365 _egg_data->set_coordinate_system(CS_invalid);
366 daeegg_cat.warning() <<
"Unrecognized coordinate system!\n";
372void DAEToEggConverter::
373process_node(
EggGroupNode *parent,
const FCDSceneNode* node,
bool forced) {
374 nassertv(node !=
nullptr);
375 string node_id = FROM_FSTRING(node->GetDaeId());
376 daeegg_cat.spam() <<
"Processing node with ID '" << node_id <<
"'" << endl;
379 PT(EggGroup) node_group =
new EggGroup(FROM_FSTRING(node->GetDaeId()));
380 process_extra(node_group, node->GetExtra());
384 if (node->IsJoint()) {
385 string sid = FROM_FSTRING(node->GetSubId());
386 node_group->set_group_type(EggGroup::GT_joint);
388 if (!_joints.insert(DaeCharacter::JointMap::value_type(sid,
389 DaeCharacter::Joint(node_group, node))).second) {
391 <<
"Joint with sid " << sid <<
" occurs more than once!\n";
396 for (
size_t tr = node->GetTransformCount(); tr > 0; --tr) {
397 apply_transform(node_group, node->GetTransform(tr - 1));
402 for (
size_t in = 0; in < node->GetInstanceCount(); ++in) {
403 process_instance(node_group, node->GetInstance(in));
407 for (
size_t ch = 0; ch < node->GetChildrenCount(); ++ch) {
408 process_node(DCAST(EggGroupNode, node_group), node->GetChild(ch));
412 for (
size_t in = 0; in < node->GetInstanceCount(); ++in) {
413 const FCDEntity *entity = node->GetInstance(in)->GetEntity();
414 if (entity && entity->GetType() == FCDEntity::SCENE_NODE) {
415 process_node(node_group, (
const FCDSceneNode*) entity);
420void DAEToEggConverter::
421process_instance(
EggGroup *parent,
const FCDEntityInstance* instance) {
422 nassertv(instance !=
nullptr);
423 nassertv(instance->GetEntity() !=
nullptr);
425 switch (instance->GetType()) {
426 case FCDEntityInstance::GEOMETRY:
429 const FCDGeometry* geometry = (
const FCDGeometry*) instance->GetEntity();
430 assert(geometry !=
nullptr);
431 if (geometry->IsMesh()) {
433 process_mesh(parent, geometry->GetMesh(),
new DaeMaterials((
const FCDGeometryInstance*) instance));
435 if (geometry->IsSpline()) {
436 process_spline(parent, FROM_FSTRING(geometry->GetName()),
const_cast<FCDGeometrySpline*
> (geometry->GetSpline()));
442 case FCDEntityInstance::CONTROLLER:
445 process_controller(parent, (
const FCDControllerInstance*) instance);
448 case FCDEntityInstance::MATERIAL:
452 case FCDEntityInstance::SIMPLE:
455 const FCDEntity* entity = instance->GetEntity();
456 if (entity->GetType() != FCDEntity::SCENE_NODE) {
457 daeegg_cat.warning() <<
"Unsupported entity type found" << endl;
463 daeegg_cat.warning() <<
"Unsupported instance type found" << endl;
468void DAEToEggConverter::
469process_mesh(
EggGroup *parent,
const FCDGeometryMesh* mesh,
472 nassertv(mesh !=
nullptr);
473 daeegg_cat.debug() <<
"Processing mesh with id " << FROM_FSTRING(mesh->GetDaeId()) << endl;
476 PT(EggGroup) mesh_group =
new EggGroup(FROM_FSTRING(mesh->GetDaeId()));
478 PT(EggVertexPool) mesh_pool =
new EggVertexPool(FROM_FSTRING(mesh->GetDaeId()));
479 mesh_group->add_child(mesh_pool);
482 if (mesh->GetSourceCount() == 0) {
483 daeegg_cat.debug() <<
"Mesh with id " << FROM_FSTRING(mesh->GetDaeId()) <<
" has no sources" << endl;
486 const FCDGeometrySource* vsource = mesh->FindSourceByType(FUDaeGeometryInput::POSITION);
487 if (vsource ==
nullptr) {
488 daeegg_cat.debug() <<
"Mesh with id " << FROM_FSTRING(mesh->GetDaeId()) <<
" has no source for POSITION data" << endl;
493 daeegg_cat.spam() <<
"Mesh with id " << FROM_FSTRING(mesh->GetDaeId()) <<
" has " << mesh->GetPolygonsCount() <<
" polygon groups" << endl;
494 if (mesh->GetPolygonsCount() == 0)
return;
498 PT(EggGroup) *primitive_holders =
new PT(EggGroup) [mesh->GetPolygonsCount()];
499 for (
size_t gr = 0; gr < mesh->GetPolygonsCount(); ++gr) {
500 const FCDGeometryPolygons* polygons = mesh->GetPolygons(gr);
501 string material_semantic = FROM_FSTRING(polygons->GetMaterialSemantic());
504 PT(EggGroup) primitiveholder;
507 if (materials !=
nullptr && (!polygons->GetMaterialSemantic().empty()) && mesh->GetPolygonsCount() > 1) {
510 primitiveholder =
new EggGroup;
511 mesh_group->add_child(primitiveholder);
513 primitiveholder = mesh_group;
515 primitive_holders[gr] = primitiveholder;
517 if (materials !=
nullptr) {
518 materials->
apply_to_group(material_semantic, primitiveholder, _invert_transparency);
521 const FCDGeometryPolygonsInput* pinput = polygons->FindInput(FUDaeGeometryInput::POSITION);
522 assert(pinput !=
nullptr);
523 const uint32* indices = pinput->GetIndices();
525 const FCDGeometrySource* nsource = mesh->FindSourceByType(FUDaeGeometryInput::NORMAL);
526 const FCDGeometryPolygonsInput* ninput = polygons->FindInput(FUDaeGeometryInput::NORMAL);
527 const uint32* nindices;
528 if (ninput !=
nullptr) nindices = ninput->GetIndices();
530 const FCDGeometrySource* tcsource = mesh->FindSourceByType(FUDaeGeometryInput::TEXCOORD);
531 const FCDGeometryPolygonsInput* tcinput = polygons->FindInput(FUDaeGeometryInput::TEXCOORD);
532 const uint32* tcindices;
533 if (tcinput !=
nullptr) tcindices = tcinput->GetIndices();
535 const FCDGeometrySource* csource = mesh->FindSourceByType(FUDaeGeometryInput::COLOR);
536 const FCDGeometryPolygonsInput* cinput = polygons->FindInput(FUDaeGeometryInput::COLOR);
537 const uint32* cindices;
538 if (cinput !=
nullptr) cindices = cinput->GetIndices();
540 const FCDGeometrySource* bsource = mesh->FindSourceByType(FUDaeGeometryInput::TEXBINORMAL);
541 const FCDGeometryPolygonsInput* binput = polygons->FindInput(FUDaeGeometryInput::TEXBINORMAL);
542 const uint32* bindices;
543 if (binput !=
nullptr) bindices = binput->GetIndices();
545 const FCDGeometrySource* tsource = mesh->FindSourceByType(FUDaeGeometryInput::TEXTANGENT);
546 const FCDGeometryPolygonsInput* tinput = polygons->FindInput(FUDaeGeometryInput::TEXTANGENT);
547 const uint32* tindices;
548 if (tinput !=
nullptr) tindices = tinput->GetIndices();
551 if (materials !=
nullptr && tcinput !=
nullptr) {
552 if (daeegg_cat.is_debug()) {
554 <<
"Assigning texcoord set " << tcinput->GetSet()
555 <<
" to semantic '" << material_semantic <<
"'\n";
558 FUDaeGeometryInput::TEXCOORD, tcinput->GetSet());
561 if (materials !=
nullptr && binput !=
nullptr) {
562 if (daeegg_cat.is_debug()) {
564 <<
"Assigning texbinormal set " << binput->GetSet()
565 <<
" to semantic '" << material_semantic <<
"'\n";
568 FUDaeGeometryInput::TEXBINORMAL, binput->GetSet());
571 if (materials !=
nullptr && tinput !=
nullptr) {
572 if (daeegg_cat.is_debug()) {
574 <<
"Assigning textangent set " << tinput->GetSet()
575 <<
" to semantic '" << material_semantic <<
"'\n";
578 FUDaeGeometryInput::TEXTANGENT, tinput->GetSet());
581 for (
size_t ix = 0; ix < pinput->GetIndexCount(); ++ix) {
582 PT_EggVertex vertex = mesh_pool->make_new_vertex();
583 const float* data = &vsource->GetData()[indices[ix]*3];
584 vertex->set_pos(LPoint3d(data[0], data[1], data[2]));
586 if (character !=
nullptr) {
592 if (nsource !=
nullptr && ninput !=
nullptr) {
593 assert(nsource->GetStride() == 3);
594 data = &nsource->GetData()[nindices[ix]*3];
595 vertex->set_normal(LVecBase3d(data[0], data[1], data[2]));
598 if (tcsource !=
nullptr && tcinput !=
nullptr) {
599 assert(tcsource->GetStride() == 2 || tcsource->GetStride() == 3);
600 data = &tcsource->GetData()[tcindices[ix]*tcsource->GetStride()];
601 if (tcsource->GetStride() == 2) {
602 vertex->set_uv(tcsetname, LPoint2d(data[0], data[1]));
604 vertex->set_uvw(tcsetname, LPoint3d(data[0], data[1], data[2]));
608 if (csource !=
nullptr && cinput !=
nullptr) {
609 assert(csource->GetStride() == 3 || csource->GetStride() == 4);
610 if (csource->GetStride() == 3) {
611 data = &csource->GetData()[cindices[ix]*3];
612 vertex->set_color(LColor(data[0], data[1], data[2], 1.0f));
614 data = &csource->GetData()[cindices[ix]*4];
615 vertex->set_color(LColor(data[0], data[1], data[2], data[3]));
619 if ((bsource !=
nullptr && binput !=
nullptr) || (tsource !=
nullptr && tinput !=
nullptr)) {
620 if (bsource !=
nullptr && binput !=
nullptr) {
621 assert(bsource->GetStride() == 3);
622 data = &bsource->GetData()[bindices[ix]*3];
623 PT(EggVertexUV) uv_obj = vertex->modify_uv_obj(tbsetname);
624 if (uv_obj ==
nullptr) {
625 uv_obj =
new EggVertexUV(tbsetname, LTexCoordd());
627 uv_obj->set_binormal(LVecBase3d(data[0], data[1], data[2]));
629 if (tsource !=
nullptr && tinput !=
nullptr) {
630 assert(tsource->GetStride() == 3);
631 data = &tsource->GetData()[tindices[ix]*3];
632 PT(EggVertexUV) uv_obj = vertex->modify_uv_obj(ttsetname);
633 if (uv_obj ==
nullptr) {
634 uv_obj =
new EggVertexUV(ttsetname, LTexCoordd());
636 uv_obj->set_tangent(LVecBase3d(data[0], data[1], data[2]));
643 for (
size_t gr = 0; gr < mesh->GetPolygonsCount(); ++gr) {
644 const FCDGeometryPolygons* polygons = mesh->GetPolygons(gr);
647 for (
size_t fa = 0; fa < polygons->GetFaceVertexCountCount(); ++fa) {
648 PT(EggPrimitive) primitive =
nullptr;
650 switch (polygons->GetPrimitiveType()) {
651 case FCDGeometryPolygons::LINES:
652 primitive =
new EggLine();
654 case FCDGeometryPolygons::POLYGONS:
655 primitive =
new EggPolygon();
657 case FCDGeometryPolygons::TRIANGLE_FANS:
658 primitive =
new EggTriangleFan();
660 case FCDGeometryPolygons::TRIANGLE_STRIPS:
661 primitive =
new EggTriangleStrip();
663 case FCDGeometryPolygons::POINTS:
664 primitive =
new EggPoint();
666 case FCDGeometryPolygons::LINE_STRIPS:
667 daeegg_cat.warning() <<
"Linestrips not yet supported!" << endl;
670 daeegg_cat.warning() <<
"Unsupported primitive type found!" << endl;
672 if (primitive !=
nullptr) {
673 primitive_holders[gr]->add_child(primitive);
674 if (materials !=
nullptr) {
675 materials->
apply_to_primitive(FROM_FSTRING(polygons->GetMaterialSemantic()), primitive);
677 for (
size_t ve = 0; ve < polygons->GetFaceVertexCount(fa); ++ve) {
678 assert(mesh_pool->has_vertex(ve + polygons->GetFaceVertexOffset() + offset));
679 primitive->add_vertex(mesh_pool->get_vertex(ve + polygons->GetFaceVertexOffset() + offset));
682 offset += polygons->GetFaceVertexCount(fa);
685 delete[] primitive_holders;
688void DAEToEggConverter::
689process_spline(
EggGroup *parent,
const string group_name, FCDGeometrySpline* geometry_spline) {
690 assert(geometry_spline !=
nullptr);
691 PT(EggGroup) result =
new EggGroup(group_name);
694 if (geometry_spline->GetType() != FUDaeSplineType::NURBS) {
695 daeegg_cat.warning() <<
"Only NURBS curves are supported (yet)!" << endl;
698 for (
size_t sp = 0; sp < geometry_spline->GetSplineCount(); ++sp) {
699 process_spline(result, geometry_spline->GetSpline(sp));
704void DAEToEggConverter::
705process_spline(
EggGroup *parent,
const FCDSpline* spline) {
706 assert(spline !=
nullptr);
707 nassertv(spline->GetSplineType() == FUDaeSplineType::NURBS);
709 PT(EggNurbsCurve) nurbs_curve =
new EggNurbsCurve(FROM_FSTRING(spline->GetName()));
712 nurbs_curve->setup(0, ((
const FCDNURBSSpline*) spline)->GetKnotCount());
713 for (
size_t kn = 0; kn < ((
const FCDNURBSSpline*) spline)->GetKnotCount(); ++kn) {
714 const float* knot = ((
const FCDNURBSSpline*) spline)->GetKnot(kn);
715 assert(knot !=
nullptr);
716 nurbs_curve->set_knot(kn, *knot);
718 for (
size_t cv = 0; cv < spline->GetCVCount(); ++cv) {
719 PT_EggVertex c_vtx =
new EggVertex();
720 c_vtx->set_pos(TO_VEC3(*spline->GetCV(cv)));
722 nurbs_curve->add_vertex(c_vtx);
726void DAEToEggConverter::
727process_controller(
EggGroup *parent,
const FCDControllerInstance *instance) {
728 assert(instance !=
nullptr);
729 const FCDController* controller = (
const FCDController *)instance->GetEntity();
730 assert(controller !=
nullptr);
734 const FCDGeometryMesh *mesh = controller->GetBaseGeometry()->GetMesh();
735 if (mesh !=
nullptr) {
736 PT(DaeMaterials) materials =
new DaeMaterials(instance);
737 daeegg_cat.spam() <<
"Processing mesh for controller\n";
738 process_mesh(parent, mesh, materials);
742 PT(DaeCharacter) character =
new DaeCharacter(parent, instance);
743 _characters.push_back(character);
746 if (controller->IsMorph()) {
747 assert(controller !=
nullptr);
748 const FCDMorphController* morph_controller = controller->GetMorphController();
749 assert(morph_controller !=
nullptr);
750 PT(EggTable) bundle =
new EggTable(parent->get_name());
751 bundle->set_table_type(EggTable::TT_bundle);
752 PT(EggTable) morph =
new EggTable(
"morph");
753 morph->set_table_type(EggTable::TT_table);
754 bundle->add_child(morph);
756 for (
size_t mt = 0; mt < morph_controller->GetTargetCount(); ++mt) {
757 const FCDMorphTarget* morph_target = morph_controller->GetTarget(mt);
758 assert(morph_target !=
nullptr);
759 PT(EggSAnimData) target =
new EggSAnimData(FROM_FSTRING(morph_target->GetGeometry()->GetName()));
760 if (morph_target->IsAnimated()) {
763 target->add_data(morph_target->GetWeight());
765 morph->add_child(target);
770void DAEToEggConverter::
771process_extra(
EggGroup *group,
const FCDExtra* extra) {
772 if (extra ==
nullptr) {
775 nassertv(group !=
nullptr);
777 const FCDEType* etype = extra->GetDefaultType();
778 if (etype ==
nullptr) {
782 const FCDENode* enode = (
const FCDENode*) etype->FindTechnique(
"PANDA3D");
783 if (enode ==
nullptr) {
788 enode->FindChildrenNodes(
"param", tags);
789 for (FCDENodeList::iterator it = tags.begin(); it != tags.end(); ++it) {
790 const FCDEAttribute* attr = (*it)->FindAttribute(
"sid");
792 group->
set_tag(FROM_FSTRING(attr->GetValue()), (*it)->GetContent());
797LMatrix4d DAEToEggConverter::
798convert_matrix(
const FMMatrix44 &matrix) {
800 matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3],
801 matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3],
802 matrix[2][0], matrix[2][1], matrix[2][2], matrix[2][3],
803 matrix[3][0], matrix[3][1], matrix[3][2], matrix[3][3]);
806void DAEToEggConverter::
807apply_transform(
EggGroup *to,
const FCDTransform* from) {
808 assert(from !=
nullptr);
809 assert(to !=
nullptr);
812 switch (from->GetType()) {
813 case FCDTransform::TRANSLATION:
815 const FCDTTranslation *trans = (
const FCDTTranslation *)from;
820 case FCDTransform::ROTATION:
822 const FCDTRotation *rot = (
const FCDTRotation *)from;
823 to->
add_rotate3d(rot->GetAngle(), TO_VEC3(rot->GetAxis()));
827 case FCDTransform::SCALE:
829 const FCDTScale *scale = (
const FCDTScale *)from;
This class supervises the construction of an EggData structure from a DAE file.
virtual SomethingToEggConverter * make_copy()
Allocates and returns a new copy of the converter.
virtual std::string get_name() const
Returns the English name of the file type this converter supports.
virtual bool convert_file(const Filename &filename)
Handles the reading of the input file and converting it to egg.
virtual DistanceUnit get_input_units()
This may be called after convert_file() has been called and returned true, indicating a successful co...
virtual std::string get_extension() const
Returns the common extension of the file type this converter supports.
Class representing an animated character.
void bind_joints(JointMap &joint_map)
Binds the joints to the character.
void influence_vertex(int index, EggVertex *vertex)
Adds the influences for the given vertex.
void build_table(EggTable *parent, FCDSceneNode *node, const pset< float > &keys)
Processes a joint node and its transforms.
void collect_keys(pset< float > &keys)
Collects all animation keys of animations applied to this character.
void adjust_joints(FCDSceneNode *node, const JointMap &joint_map, const LMatrix4d &transform=LMatrix4d::ident_mat())
Traverses through the character hierarchy in order to bind the mesh to the character.
This class is seperated from the converter file because otherwise it would get too big and needlessly...
const std::string get_uvset_name(const std::string semantic, FUDaeGeometryInput::Semantic input_semantic, int32 input_set)
Returns the semantic of the uvset with the specified input set, or an empty string if the given mater...
void apply_to_group(const std::string semantic, const PT(EggGroup) to, bool invert_transparency=false)
Applies the colorblend stuff to the given EggGroup.
void apply_to_primitive(const std::string semantic, const PT(EggPrimitive) to)
Applies the stuff to the given EggPrimitive.
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_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.
const LMatrix4d & get_node_to_vertex() const
Returns the transformation matrix suitable for converting vertices in the coordinate space of the nod...
This corresponds to a a <Bundle> entry.
The name of a file, such as a texture file or an Egg file.
This is a base class for a family of converter classes that manage a conversion from some file type t...
AnimationConvert get_animation_convert() const
Returns how source animation will be converted into egg structures.
void clear_error()
Resets the error flag to the no-error state.
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.
DistanceUnit
This enumerated type lists all the kinds of units we're likely to come across in model conversion pro...
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.