Revision: 48905
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=48905
Author:   phabtar
Date:     2012-07-14 03:37:39 +0000 (Sat, 14 Jul 2012)
Log Message:
-----------
IK constraint animation export.(not complete)

Modified Paths:
--------------
    branches/soc-2012-bratwurst/source/blender/collada/AnimationExporter.cpp
    branches/soc-2012-bratwurst/source/blender/collada/AnimationExporter.h
    branches/soc-2012-bratwurst/source/blender/collada/CMakeLists.txt
    branches/soc-2012-bratwurst/source/blender/collada/TransformWriter.cpp

Modified: 
branches/soc-2012-bratwurst/source/blender/collada/AnimationExporter.cpp
===================================================================
--- branches/soc-2012-bratwurst/source/blender/collada/AnimationExporter.cpp    
2012-07-14 03:35:25 UTC (rev 48904)
+++ branches/soc-2012-bratwurst/source/blender/collada/AnimationExporter.cpp    
2012-07-14 03:37:39 UTC (rev 48905)
@@ -24,6 +24,8 @@
 #include "AnimationExporter.h"
 #include "MaterialExporter.h"
 
+Global G;
+
 template<class Functor>
 void forEachObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set)
 {
@@ -831,6 +833,10 @@
     
        bPoseChannel *parchan = NULL;
        bPoseChannel *pchan = NULL;
+       bPoseChannel *rootchan = NULL;
+       bPoseChannel *itrpchan;
+       float actframe = BKE_nla_tweakedit_remap(ob->adt, (float)CFRA, 0);
+
        if (ob->type == OB_ARMATURE ){
                bPose *pose = ob->pose;
                pchan = BKE_pose_channel_find_name(pose, bone->name);
@@ -841,25 +847,49 @@
 
                enable_fcurves(ob->adt->action, bone->name);
        }
+       
        std::vector<float>::iterator it;
        int j = 0;
        for (it = frames.begin(); it != frames.end(); it++) {
                float mat[4][4], ipar[4][4];
-
+        
                float ctime = BKE_scene_frame_get_from_ctime(scene, *it);
+               CFRA = BKE_scene_frame_get_from_ctime(scene, *it);
+               BKE_scene_update_for_newframe(G.main,scene,scene->lay);
+               //BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, ctime, 
ADT_RECALC_ALL);
+               BKE_pose_where_is(scene, ob);
+               
+               if (bone){
+                       //if( pchan->flag & POSE_CHAIN)
+                       //{
+                       //      for (itrpchan = 
(bPoseChannel*)ob->pose->chanbase.first; itrpchan; itrpchan = itrpchan->next) {
+                       //              itrpchan->flag &= ~(POSE_DONE | 
POSE_CHAIN | POSE_IKTREE | POSE_IKSPLINE);
+                       //      }
+                       //      rootchan = pchan;
+                       //      while(rootchan->parent){
+                       //              rootchan = rootchan->parent;
+                       //      }
+                       //      BIK_initialize_tree(scene, ob, ctime);
+                       //      
+                       //      for (itrpchan = 
(bPoseChannel*)ob->pose->chanbase.first; itrpchan; itrpchan = itrpchan->next) {
+                       //              if (itrpchan->flag & POSE_IKTREE) {
+                       //                      BIK_execute_tree(scene, ob, 
itrpchan, ctime);
+                       //              }
+                       //              /*else if (itrpchan->flag & 
POSE_IKSPLINE) {
+                       //                      splineik_execute_tree(scene, 
ob, itrpchan, ctime);
+                       //              }*/
+                       //              else if (!(itrpchan->flag & POSE_DONE)) 
{
+                       //                      BKE_pose_where_is_bone(scene, 
ob, itrpchan, ctime, 1);
+                       //              }
+                       //      }
 
-               BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, ctime, 
ADT_RECALC_ANIM);
-               if (bone){
-                       /* 4a. if we find an IK root, we handle it separated */
-                       if (pchan->flag & POSE_IKTREE) {
-                               BIK_execute_tree(scene, ob, pchan, ctime);
-                       }
-                       ///* 4b. if we find a Spline IK root, we handle it 
separated too */
-                       //else if (pchan->flag & POSE_IKSPLINE) {
-                       //      splineik_execute_tree(scene, ob, pchan, ctime);
+                       //      BIK_release_tree(scene, ob, ctime);
+                       //      /*if (rootchan->flag & POSE_IKTREE) 
+                       //      CAE_execute_tree(scene, ob, rootchan, ctime);*/
                        //}
+                       //else
+                       //BKE_pose_where_is_bone(scene, ob, pchan, ctime, 1);
                        
-                       BKE_pose_where_is_bone(scene, ob, pchan, ctime, 1);
                        // compute bone local mat
                        if (bone->parent) {
                                invert_m4_m4(ipar, parchan->pose_mat);
@@ -892,6 +922,8 @@
                        calc_ob_mat_at_time(ob, ctime, mat);
                }
                
+               //BIK_release_tree(scene, ob, ctime);
+
                UnitConverter converter;
 
                double outmat[4][4];
@@ -902,10 +934,14 @@
                j++;
        }
 
-       //enable_fcurves(ob->adt->action, NULL);
+       enable_fcurves(ob->adt->action, NULL);
 
        source.finish();
 
+       /*BKE_pose_free(posen);
+       ob->pose = poseo;
+       BKE_pose_rebuild(ob, (bArmature*)ob->data);*/
+
        return source_id;
 }
 
@@ -1455,3 +1491,336 @@
        copy_m4_m4(mat, ob->obmat);
 }
 
+void AnimationExporter::CAE_execute_tree( struct Scene *scene, Object *ob, 
bPoseChannel *pchan, float ctime){
+       while (pchan->iktree.first) {
+               PoseTree *tree = (PoseTree*)pchan->iktree.first;
+               int a;
+
+               /* stop on the first tree that isn't a standard IK chain */
+               if (tree->type != CONSTRAINT_TYPE_KINEMATIC)
+                       return;
+
+               /* 4. walk over the tree for regular solving */
+               for (a = 0; a < tree->totchannel; a++) {
+                       if (!(tree->pchan[a]->flag & POSE_DONE))    // 
successive trees can set the flag
+                               BKE_pose_where_is_bone(scene, ob, 
tree->pchan[a], ctime, 1);
+                       // tell blender that this channel was controlled by IK, 
it's cleared on each BKE_pose_where_is()
+                       tree->pchan[a]->flag |= POSE_CHAIN;
+               }
+               /* 5. execute the IK solver */
+               execute_posetree_ctime(scene, ob, tree, ctime);
+
+               /* 6. apply the differences to the channels,
+                *    we need to calculate the original differences first */
+               for (a = 0; a < tree->totchannel; a++) {
+                       if (tree->pchan[a]->parent) {
+                               float iR_parmat[4][4];
+                               invert_m4_m4(iR_parmat, 
tree->pchan[a]->parent->pose_mat);
+                               mult_m4_m4m4(tree->pchan[a]->chan_mat, 
iR_parmat,  tree->pchan[a]->pose_mat); // delta mat
+                       }
+                       else copy_m4_m4(tree->pchan[a]->chan_mat, 
tree->pchan[a]->pose_mat);
+               }
+
+               for (a = 0; a < tree->totchannel; a++) {
+                       /* sets POSE_DONE */
+                       where_is_ik_bone(tree->pchan[a], tree->basis_change[a]);
+               }
+
+               /* 7. and free */
+               BLI_remlink(&pchan->iktree, tree);
+               free_posetree(tree);
+       }
+}
+
+void AnimationExporter::execute_posetree_ctime(struct Scene *scene, Object 
*ob, PoseTree *tree, float ctime){
+       float R_parmat[3][3], identity[3][3];
+       float iR_parmat[3][3];
+       float R_bonemat[3][3];
+       float goalrot[3][3], goalpos[3];
+       float rootmat[4][4], imat[4][4];
+       float goal[4][4], goalinv[4][4];
+       float irest_basis[3][3], full_basis[3][3];
+       float end_pose[4][4], world_pose[4][4];
+       float length, basis[3][3], rest_basis[3][3], start[3], *ikstretch = 
NULL;
+       float resultinf = 0.0f;
+       int a, flag, hasstretch = 0, resultblend = 0;
+       bPoseChannel *pchan;
+       IK_Segment *seg, *parent, **iktree, *iktarget;
+       IK_Solver *solver;
+       PoseTarget *target;
+       bKinematicConstraint *data, *poleangledata = NULL;
+       Bone *bone;
+
+       if (tree->totchannel == 0)
+               return;
+
+       iktree = (IK_Segment **)MEM_mallocN(sizeof(void *) * tree->totchannel, 
"ik tree");
+
+       for (a = 0; a < tree->totchannel; a++) {
+               pchan = tree->pchan[a];
+               bone = pchan->bone;
+
+               /* set DoF flag */
+               flag = 0;
+               if (!(pchan->ikflag & BONE_IK_NO_XDOF) && !(pchan->ikflag & 
BONE_IK_NO_XDOF_TEMP))
+                       flag |= IK_XDOF;
+               if (!(pchan->ikflag & BONE_IK_NO_YDOF) && !(pchan->ikflag & 
BONE_IK_NO_YDOF_TEMP))
+                       flag |= IK_YDOF;
+               if (!(pchan->ikflag & BONE_IK_NO_ZDOF) && !(pchan->ikflag & 
BONE_IK_NO_ZDOF_TEMP))
+                       flag |= IK_ZDOF;
+
+               if (tree->stretch && (pchan->ikstretch > 0.0f)) {
+                       flag |= IK_TRANS_YDOF;
+                       hasstretch = 1;
+               }
+
+               seg = iktree[a] = IK_CreateSegment(flag);
+
+               /* find parent */
+               if (a == 0)
+                       parent = NULL;
+               else
+                       parent = iktree[tree->parent[a]];
+
+               IK_SetParent(seg, parent);
+
+               /* get the matrix that transforms from prevbone into this bone 
*/
+               copy_m3_m4(R_bonemat, pchan->pose_mat);
+
+               /* gather transformations for this IK segment */
+
+               if (pchan->parent)
+                       copy_m3_m4(R_parmat, pchan->parent->pose_mat);
+               else
+                       unit_m3(R_parmat);
+
+               /* bone offset */
+               if (pchan->parent && (a > 0))
+                       sub_v3_v3v3(start, pchan->pose_head, 
pchan->parent->pose_tail);
+               else
+                       /* only root bone (a = 0) has no parent */
+                       start[0] = start[1] = start[2] = 0.0f;
+
+               /* change length based on bone size */
+               length = bone->length * len_v3(R_bonemat[1]);
+
+               /* compute rest basis and its inverse */
+               copy_m3_m3(rest_basis, bone->bone_mat);
+               copy_m3_m3(irest_basis, bone->bone_mat);
+               transpose_m3(irest_basis);
+
+               /* compute basis with rest_basis removed */
+               invert_m3_m3(iR_parmat, R_parmat);
+               mul_m3_m3m3(full_basis, iR_parmat, R_bonemat);
+               mul_m3_m3m3(basis, irest_basis, full_basis);
+
+               /* basis must be pure rotation */
+               normalize_m3(basis);
+
+               /* transform offset into local bone space */
+               normalize_m3(iR_parmat);
+               mul_m3_v3(iR_parmat, start);
+
+               IK_SetTransform(seg, start, rest_basis, basis, length);
+
+               if (pchan->ikflag & BONE_IK_XLIMIT)
+                       IK_SetLimit(seg, IK_X, pchan->limitmin[0], 
pchan->limitmax[0]);
+               if (pchan->ikflag & BONE_IK_YLIMIT)
+                       IK_SetLimit(seg, IK_Y, pchan->limitmin[1], 
pchan->limitmax[1]);
+               if (pchan->ikflag & BONE_IK_ZLIMIT)
+                       IK_SetLimit(seg, IK_Z, pchan->limitmin[2], 
pchan->limitmax[2]);
+
+               IK_SetStiffness(seg, IK_X, pchan->stiffness[0]);
+               IK_SetStiffness(seg, IK_Y, pchan->stiffness[1]);
+               IK_SetStiffness(seg, IK_Z, pchan->stiffness[2]);
+
+               if (tree->stretch && (pchan->ikstretch > 0.0f)) {
+                       float ikstretch = pchan->ikstretch * pchan->ikstretch;
+                       IK_SetStiffness(seg, IK_TRANS_Y, MIN2(1.0f - ikstretch, 
0.99f));
+                       IK_SetLimit(seg, IK_TRANS_Y, 0.001, 1e10);
+               }
+       }
+
+       solver = IK_CreateSolver(iktree[0]);
+
+       /* set solver goals */
+
+       /* first set the goal inverse transform, assuming the root of tree was 
done ok! */
+       pchan = tree->pchan[0];
+       if (pchan->parent) {
+               /* transform goal by parent mat, so this rotation is not part 
of the
+                * segment's basis. otherwise rotation limits do not work on the
+                * local transform of the segment itself. */
+               copy_m4_m4(rootmat, pchan->parent->pose_mat);
+               /* However, we do not want to get (i.e. reverse) parent's 
scale, as it generates [#31008]
+                * kind of nasty bugs... */
+               normalize_m4(rootmat);
+       }
+       else
+               unit_m4(rootmat);
+       copy_v3_v3(rootmat[3], pchan->pose_head);
+
+       mult_m4_m4m4(imat, ob->obmat, rootmat);
+       invert_m4_m4(goalinv, imat);
+
+       for (target = (PoseTarget *)tree->targets.first; target; target = 
target->next) {
+               float polepos[3];
+               int poleconstrain = 0;
+
+               data = (bKinematicConstraint *)target->con->data;
+
+               get_constraint_target_matrix(scene, target->con, 0, 
CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, ctime);
+
+               /* and set and transform goal */
+               mult_m4_m4m4(goal, goalinv, rootmat);
+
+               copy_v3_v3(goalpos, goal[3]);
+               copy_m3_m4(goalrot, goal);
+
+               /* same for pole vector target */
+               if (data->poletar) {
+                       get_constraint_target_matrix(scene, target->con, 1, 
CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, ctime);
+
+                       if (data->flag & CONSTRAINT_IK_SETANGLE) {
+                               /* don't solve IK when we are setting the pole 
angle */
+                               break;
+                       }
+                       else {
+                               mult_m4_m4m4(goal, goalinv, rootmat);
+                               copy_v3_v3(polepos, goal[3]);
+                               poleconstrain = 1;
+
+                               /* for pole targets, we blend the result of the 
ik solver
+                                * instead of the target position, otherwise we 
can't get
+                                * a smooth transition */
+                               resultblend = 1;
+                               resultinf = target->con->enforce;
+
+                               if (data->flag & CONSTRAINT_IK_GETANGLE) {
+                                       poleangledata = data;
+                                       data->flag &= ~CONSTRAINT_IK_GETANGLE;
+                               }
+                       }
+               }
+

@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to