[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [48905] branches/soc-2012-bratwurst/source /blender/collada: IK constraint animation export.(not complete)
Sukhitha Jayathilake
pr.jayathilake at gmail.com
Sat Jul 14 05:37:40 CEST 2012
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. @@
More information about the Bf-blender-cvs
mailing list