15 #include "daeCharacter.h" 16 #include "config_daeegg.h" 17 #include "fcollada_utils.h" 18 #include "pt_EggVertex.h" 19 #include "eggXfmSAnim.h" 20 #include "daeToEggConverter.h" 21 #include "daeMaterials.h" 23 #include "eggExternalReference.h" 25 #include "FCDocument/FCDocument.h" 26 #include "FCDocument/FCDController.h" 27 #include "FCDocument/FCDGeometry.h" 28 #include "FCDocument/FCDSceneNodeTools.h" 30 #include "FCDocument/FCDSceneNode.h" 31 #include "FCDocument/FCDTransform.h" 32 #include "FCDocument/FCDAnimated.h" 33 #include "FCDocument/FCDAnimationCurve.h" 34 #include "FCDocument/FCDAnimationKey.h" 44 DaeCharacter(
EggGroup *node_group,
const FCDControllerInstance *instance) :
45 _node_group(node_group),
46 _name(node_group->get_name()),
48 _skin_controller(NULL),
54 const FCDController *controller = (
const FCDController *)instance->GetEntity();
55 if (controller == NULL) {
58 _skin_mesh = controller->GetBaseGeometry()->GetMesh();
60 if (controller->IsSkin()) {
61 _skin_controller = controller->GetSkinController();
62 _bind_shape_mat = DAEToEggConverter::convert_matrix(_skin_controller->GetBindShapeTransform());
79 size_t num_joints = _skin_controller->GetJointCount();
80 _joints.reserve(num_joints);
83 for (
size_t j = 0; j < num_joints; ++j) {
84 const FCDSkinControllerJoint *skin_joint = _skin_controller->GetJoint(j);
85 string sid = FROM_FSTRING(skin_joint->GetId());
87 bind_pose.
invert_from(DAEToEggConverter::convert_matrix(
88 skin_joint->GetBindPoseInverse()));
91 JointMap::iterator ji = joint_map.find(sid);
92 if (ji != joint_map.end()) {
93 Joint &joint = ji->second;
102 <<
"Multiple controllers share joint with sid " << sid
103 <<
", with different bind poses.\n";
107 joint._bind_pose = bind_pose;
108 joint._character =
this;
111 _joints.push_back(joint);
114 <<
"Unknown joint sid being referenced: '" << sid <<
"'\n";
117 _joints.push_back(
Joint(NULL, NULL));
137 if (node->IsJoint()) {
138 string sid = FROM_FSTRING(node->GetSubId());
140 JointMap::const_iterator ji = joint_map.find(sid);
141 if (ji != joint_map.end()) {
142 const Joint &joint = ji->second;
148 if (joint._character ==
this) {
149 LMatrix4d bind_pose = joint._bind_pose * _bind_shape_mat *
154 this_transform = bind_pose * this_transform;
155 joint._group->set_default_pose(*joint._group);
156 joint._group->set_transform3d(bind_pose);
172 for (
size_t ch = 0; ch < node->GetChildrenCount(); ++ch) {
174 adjust_joints(node->GetChild(ch), joint_map, this_transform);
186 const FCDSkinControllerVertex *influence = _skin_controller->GetVertexInfluence(index);
188 for (
size_t pa = 0; pa < influence->GetPairCount(); ++pa) {
189 const FCDJointWeightPair* jwpair = influence->GetPair(pa);
191 if (jwpair->jointIndex >= 0 && jwpair->jointIndex < _joints.size()) {
192 EggGroup *joint = _joints[jwpair->jointIndex]._group.p();
198 <<
"Invalid joint index: " << jwpair->jointIndex <<
"\n";
211 #if FCOLLADA_VERSION < 0x00030005 212 FCDSceneNodeList roots = _instance->FindSkeletonNodes();
214 FCDSceneNodeList roots;
215 _instance->FindSkeletonNodes(roots);
218 for (FCDSceneNodeList::iterator it = roots.begin(); it != roots.end(); ++it) {
231 FCDAnimatedList animateds;
234 for (
size_t t = 0; t < node->GetTransformCount(); ++t) {
235 FCDTransform *transform = node->GetTransform(t);
236 FCDAnimated *animated = transform->GetAnimated();
238 if (animated != NULL) {
239 const FCDAnimationCurveListList &all_curves = animated->GetCurves();
241 for (
size_t ci = 0; ci < all_curves.size(); ++ci) {
242 const FCDAnimationCurveTrackList &curves = all_curves[ci];
243 if (curves.empty()) {
247 size_t num_keys = curves.front()->GetKeyCount();
248 const FCDAnimationKey **curve_keys = curves.front()->GetKeys();
250 for (
size_t c = 0; c < num_keys; ++c) {
251 keys.insert(curve_keys[c]->input);
265 nassertv(node != NULL);
267 if (!node->IsJoint()) {
268 for (
size_t ch = 0; ch < node->GetChildrenCount(); ++ch) {
274 string node_id = FROM_FSTRING(node->GetDaeId());
276 table->set_table_type(EggTable::TT_table);
280 table->add_child(xform);
283 FCDAnimatedList animateds;
286 for (
size_t t = 0; t < node->GetTransformCount(); ++t) {
287 FCDTransform *transform = node->GetTransform(t);
288 FCDAnimated *animated = transform->GetAnimated();
289 if (animated != (FCDAnimated *)NULL) {
290 if (animated->HasCurve()) {
291 animateds.push_back(animated);
298 float timing_total = 0;
300 for (ki = keys.begin(); ki != keys.end(); ++ki) {
301 for (FCDAnimatedList::iterator it = animateds.begin(); it != animateds.end(); ++it) {
303 (*it)->Evaluate(*ki);
306 if (ki != keys.begin()) {
307 timing_total += (*ki - last_key);
312 FMMatrix44 fmat = node->ToMatrix();
315 if (IS_NEARLY_ZERO(fmat[3][3])) {
319 xform->add_data(DAEToEggConverter::convert_matrix(fmat));
323 float fps = cfloor(((keys.size() - 1) / timing_total) * 100 + 0.5f) * 0.01f;
327 for (
size_t ch = 0; ch < node->GetChildrenCount(); ++ch) {
This is a 4-by-4 transform matrix.
void r_collect_keys(FCDSceneNode *node, pset< float > &keys)
Collects all animation keys found for the given node tree.
bool almost_equal(const LMatrix4d &other, double threshold) const
Returns true if two matrices are memberwise equal within a specified tolerance.
Class representing an animated character.
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
void influence_vertex(int index, EggVertex *vertex)
Adds the influences for the given vertex.
static const LMatrix4d & ident_mat()
Returns an identity matrix.
Any one-, two-, three-, or four-component vertex, possibly with attributes such as a normal...
void bind_joints(JointMap &joint_map)
Binds the joints to the character.
This corresponds to an <Xfm$Anim_S$> entry, which is a collection of up to nine <S$Anim> entries that...
bool invert_from(const LMatrix4d &other)
Computes the inverse of the other matrix, and stores the result in this matrix.
EggNode * add_child(EggNode *node)
Adds the indicated child to the group and returns it.
void ref_vertex(EggVertex *vert, double membership=1.0)
Adds the vertex to the set of those referenced by the group, at the indicated membership level...
This is our own Panda specialization on the default STL set.
void build_table(EggTable *parent, FCDSceneNode *node, const pset< float > &keys)
Processes a joint node and its transforms.
TypeHandle is the identifier used to differentiate C++ class types.
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.