Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/armature.c')
-rw-r--r--source/blender/blenkernel/intern/armature.c248
1 files changed, 75 insertions, 173 deletions
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index c1998d705ad..41821f34ba8 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -45,6 +45,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_nla_types.h"
#include "DNA_scene_types.h"
+#include "DNA_object_types.h"
#include "BKE_animsys.h"
#include "BKE_armature.h"
@@ -54,6 +55,7 @@
#include "BKE_curve.h"
#include "BKE_depsgraph.h"
#include "BKE_DerivedMesh.h"
+#include "BKE_deform.h"
#include "BKE_displist.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
@@ -65,10 +67,6 @@
#include "BIK_api.h"
#include "BKE_sketch.h"
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
/* **************** Generic Functions, data level *************** */
bArmature *add_armature(char *name)
@@ -248,131 +246,20 @@ Bone *get_named_bone (bArmature *arm, const char *name)
return bone;
}
-
-#define IS_SEPARATOR(a) (a=='.' || a==' ' || a=='-' || a=='_')
-
-/* finds the best possible flipped name. For renaming; check for unique names afterwards */
-/* if strip_number: removes number extensions */
-void bone_flip_name (char *name, int strip_number)
-{
- int len;
- char prefix[128]={""}; /* The part before the facing */
- char suffix[128]={""}; /* The part after the facing */
- char replace[128]={""}; /* The replacement string */
- char number[128]={""}; /* The number extension string */
- char *index=NULL;
-
- len= strlen(name);
- if(len<3) return; // we don't do names like .R or .L
-
- /* We first check the case with a .### extension, let's find the last period */
- if(isdigit(name[len-1])) {
- index= strrchr(name, '.'); // last occurrence
- if (index && isdigit(index[1]) ) { // doesnt handle case bone.1abc2 correct..., whatever!
- if(strip_number==0)
- strcpy(number, index);
- *index= 0;
- len= strlen(name);
- }
- }
-
- strcpy (prefix, name);
-
- /* first case; separator . - _ with extensions r R l L */
- if( IS_SEPARATOR(name[len-2]) ) {
- switch(name[len-1]) {
- case 'l':
- prefix[len-1]= 0;
- strcpy(replace, "r");
- break;
- case 'r':
- prefix[len-1]= 0;
- strcpy(replace, "l");
- break;
- case 'L':
- prefix[len-1]= 0;
- strcpy(replace, "R");
- break;
- case 'R':
- prefix[len-1]= 0;
- strcpy(replace, "L");
- break;
- }
- }
- /* case; beginning with r R l L , with separator after it */
- else if( IS_SEPARATOR(name[1]) ) {
- switch(name[0]) {
- case 'l':
- strcpy(replace, "r");
- strcpy(suffix, name+1);
- prefix[0]= 0;
- break;
- case 'r':
- strcpy(replace, "l");
- strcpy(suffix, name+1);
- prefix[0]= 0;
- break;
- case 'L':
- strcpy(replace, "R");
- strcpy(suffix, name+1);
- prefix[0]= 0;
- break;
- case 'R':
- strcpy(replace, "L");
- strcpy(suffix, name+1);
- prefix[0]= 0;
- break;
- }
- }
- else if(len > 5) {
- /* hrms, why test for a separator? lets do the rule 'ultimate left or right' */
- index = BLI_strcasestr(prefix, "right");
- if (index==prefix || index==prefix+len-5) {
- if(index[0]=='r')
- strcpy (replace, "left");
- else {
- if(index[1]=='I')
- strcpy (replace, "LEFT");
- else
- strcpy (replace, "Left");
- }
- *index= 0;
- strcpy (suffix, index+5);
- }
- else {
- index = BLI_strcasestr(prefix, "left");
- if (index==prefix || index==prefix+len-4) {
- if(index[0]=='l')
- strcpy (replace, "right");
- else {
- if(index[1]=='E')
- strcpy (replace, "RIGHT");
- else
- strcpy (replace, "Right");
- }
- *index= 0;
- strcpy (suffix, index+4);
- }
- }
- }
-
- sprintf (name, "%s%s%s%s", prefix, replace, suffix, number);
-}
-
/* Finds the best possible extension to the name on a particular axis. (For renaming, check for unique names afterwards)
* This assumes that bone names are at most 32 chars long!
* strip_number: removes number extensions (TODO: not used)
* axis: the axis to name on
* head/tail: the head/tail co-ordinate of the bone on the specified axis
*/
-void bone_autoside_name (char *name, int strip_number, short axis, float head, float tail)
+int bone_autoside_name (char *name, int strip_number, short axis, float head, float tail)
{
unsigned int len;
char basename[32]={""};
char extension[5]={""};
len= strlen(name);
- if (len == 0) return;
+ if (len == 0) return 0;
strcpy(basename, name);
/* Figure out extension to append:
@@ -466,9 +353,15 @@ void bone_autoside_name (char *name, int strip_number, short axis, float head, f
if ((32 - len) < strlen(extension) + 1) { /* add 1 for the '.' */
strncpy(name, basename, len-strlen(extension));
}
+
+ sprintf(name, "%s.%s", basename, extension);
+
+ return 1;
}
- sprintf(name, "%s.%s", basename, extension);
+ else {
+ return 0;
+ }
}
/* ************* B-Bone support ******************* */
@@ -684,11 +577,11 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest)
/* ************ Armature Deform ******************* */
-static void pchan_b_bone_defmats(bPoseChannel *pchan, int use_quaternion, int rest_def)
+static void pchan_b_bone_defmats(bPoseChannel *pchan, int use_quaternion)
{
Bone *bone= pchan->bone;
Mat4 *b_bone= b_bone_spline_setup(pchan, 0);
- Mat4 *b_bone_rest= (rest_def)? NULL: b_bone_spline_setup(pchan, 1);
+ Mat4 *b_bone_rest= b_bone_spline_setup(pchan, 1);
Mat4 *b_bone_mats;
DualQuat *b_bone_dual_quats= NULL;
float tmat[4][4];
@@ -715,10 +608,7 @@ static void pchan_b_bone_defmats(bPoseChannel *pchan, int use_quaternion, int re
unit_m4(tmat);
for(a=0; a<bone->segments; a++) {
- if(b_bone_rest)
- invert_m4_m4(tmat, b_bone_rest[a].mat);
- else
- tmat[3][1] = -a*(bone->length/(float)bone->segments);
+ invert_m4_m4(tmat, b_bone_rest[a].mat);
mul_serie_m4(b_bone_mats[a+1].mat, pchan->chan_mat, bone->arm_mat,
b_bone[a].mat, tmat, b_bone_mats[0].mat, NULL, NULL, NULL);
@@ -847,9 +737,8 @@ static float dist_bone_deform(bPoseChannel *pchan, float *vec, DualQuat *dq, flo
mul_m4_v3(pchan->chan_mat, cop);
// Make this a delta from the base position
- sub_v3_v3v3(cop, cop, co);
- cop[0]*=fac; cop[1]*=fac; cop[2]*=fac;
- add_v3_v3v3(vec, vec, cop);
+ sub_v3_v3(cop, co);
+ madd_v3_v3fl(vec, cop, fac);
if(mat)
pchan_deform_mat_add(pchan, fac, bbonemat, mat);
@@ -917,12 +806,11 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
float obinv[4][4], premat[4][4], postmat[4][4];
int use_envelope = deformflag & ARM_DEF_ENVELOPE;
int use_quaternion = deformflag & ARM_DEF_QUATERNION;
- int bbone_rest_def = deformflag & ARM_DEF_B_BONE_REST;
int invert_vgroup= deformflag & ARM_DEF_INVERT_VGROUP;
int numGroups = 0; /* safety for vertexgroup index overflow */
int i, target_totvert = 0; /* safety for vertexgroup overflow */
int use_dverts = 0;
- int armature_def_nr = -1;
+ int armature_def_nr;
int totchan;
if(arm->edbo) return;
@@ -944,7 +832,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
for(pchan = armOb->pose->chanbase.first; pchan; pchan = pchan->next) {
if(!(pchan->bone->flag & BONE_NO_DEFORM)) {
if(pchan->bone->segments > 1)
- pchan_b_bone_defmats(pchan, use_quaternion, bbone_rest_def);
+ pchan_b_bone_defmats(pchan, use_quaternion);
if(use_quaternion) {
pchan->dual_quat= &dualquats[totchan++];
@@ -954,26 +842,28 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
}
/* get the def_nr for the overall armature vertex group if present */
- for(i = 0, dg = target->defbase.first; dg; i++, dg = dg->next)
- if(defgrp_name && strcmp(defgrp_name, dg->name) == 0)
- armature_def_nr = i;
-
+ armature_def_nr= defgroup_name_index(target, defgrp_name);
+
+ if(ELEM(target->type, OB_MESH, OB_LATTICE)) {
+ numGroups = BLI_countlist(&target->defbase);
+
+ if(target->type==OB_MESH) {
+ Mesh *me= target->data;
+ dverts = me->dvert;
+ if(dverts)
+ target_totvert = me->totvert;
+ }
+ else {
+ Lattice *lt= target->data;
+ dverts = lt->dvert;
+ if(dverts)
+ target_totvert = lt->pntsu*lt->pntsv*lt->pntsw;
+ }
+ }
+
/* get a vertex-deform-index to posechannel array */
if(deformflag & ARM_DEF_VGROUP) {
if(ELEM(target->type, OB_MESH, OB_LATTICE)) {
- numGroups = BLI_countlist(&target->defbase);
-
- if(target->type==OB_MESH) {
- Mesh *me= target->data;
- dverts = me->dvert;
- target_totvert = me->totvert;
- }
- else {
- Lattice *lt= target->data;
- dverts = lt->dvert;
- if(dverts)
- target_totvert = lt->pntsu*lt->pntsv*lt->pntsw;
- }
/* if we have a DerivedMesh, only use dverts if it has them */
if(dm)
if(dm->getVertData(dm, 0, CD_MDEFORMVERT))
@@ -1105,9 +995,9 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
if(armature_weight != 1.0f) {
VECCOPY(dco, co);
mul_v3m3_dq( dco, (defMats)? summat: NULL,dq);
- sub_v3_v3v3(dco, dco, co);
+ sub_v3_v3(dco, co);
mul_v3_fl(dco, armature_weight);
- add_v3_v3v3(co, co, dco);
+ add_v3_v3(co, dco);
}
else
mul_v3m3_dq( co, (defMats)? summat: NULL,dq);
@@ -1393,9 +1283,8 @@ void vec_roll_to_mat3(float *vec, float roll, float mat[][3])
float nor[3], axis[3], target[3]={0,1,0};
float theta;
float rMatrix[3][3], bMatrix[3][3];
-
- VECCOPY (nor, vec);
- normalize_v3(nor);
+
+ normalize_v3_v3(nor, vec);
/* Find Axis & Amount for bone matrix*/
cross_v3_v3v3(axis,target,nor);
@@ -1564,9 +1453,11 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
* 1. extract constraints not from proxy (CONSTRAINT_PROXY_LOCAL) from pchan's constraints
* 2. copy proxy-pchan's constraints on-to new
* 3. add extracted local constraints back on top
+ *
+ * note for copy_constraints: when copying constraints, disable 'do_extern' otherwise we get the libs direct linked in this blend.
*/
extract_proxylocal_constraints(&proxylocal_constraints, &pchan->constraints);
- copy_constraints(&pchanw.constraints, &pchanp->constraints);
+ copy_constraints(&pchanw.constraints, &pchanp->constraints, FALSE);
addlisttolist(&pchanw.constraints, &proxylocal_constraints);
/* constraints - set target ob pointer to own object */
@@ -1695,6 +1586,8 @@ void armature_rebuild_pose(Object *ob, bArmature *arm)
ob->pose->flag &= ~POSE_RECALC;
ob->pose->flag |= POSE_WAS_REBUILT;
+
+ make_pose_channels_hash(ob->pose);
}
@@ -1769,20 +1662,13 @@ static void splineik_init_tree_from_pchan(Scene *scene, Object *ob, bPoseChannel
/* find the root bone and the chain of bones from the root to the tip
* NOTE: this assumes that the bones are connected, but that may not be true...
*/
- for (pchan= pchan_tip; pchan; pchan= pchan->parent) {
+ for (pchan= pchan_tip; pchan && (segcount < ikData->chainlen); pchan= pchan->parent, segcount++) {
/* store this segment in the chain */
pchanChain[segcount]= pchan;
/* if performing rebinding, calculate the length of the bone */
boneLengths[segcount]= pchan->bone->length;
totLength += boneLengths[segcount];
-
- /* check if we've gotten the number of bones required yet (after incrementing the count first)
- * NOTE: the 255 limit here is rather ugly, but the standard IK does this too!
- */
- segcount++;
- if ((segcount == ikData->chainlen) || (segcount > 255))
- break;
}
if (segcount == 0)
@@ -1940,7 +1826,7 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *o
}
/* tail endpoint */
- if ( where_on_path(ikData->tar, tree->points[index], vec, dir, NULL, &rad) ) {
+ if ( where_on_path(ikData->tar, tree->points[index], vec, dir, NULL, &rad, NULL) ) {
/* apply curve's object-mode transforms to the position
* unless the option to allow curve to be positioned elsewhere is activated (i.e. no root)
*/
@@ -1956,7 +1842,7 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *o
}
/* head endpoint */
- if ( where_on_path(ikData->tar, tree->points[index+1], vec, dir, NULL, &rad) ) {
+ if ( where_on_path(ikData->tar, tree->points[index+1], vec, dir, NULL, &rad, NULL) ) {
/* apply curve's object-mode transforms to the position
* unless the option to allow curve to be positioned elsewhere is activated (i.e. no root)
*/
@@ -2005,6 +1891,11 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *o
rangle= dot_v3v3(rmat[1], splineVec);
rangle= acos( MAX2(-1.0f, MIN2(1.0f, rangle)) );
+ /* multiply the magnitude of the angle by the influence of the constraint to
+ * control the influence of the SplineIK effect
+ */
+ rangle *= tree->con->enforce;
+
/* construct rotation matrix from the axis-angle rotation found above
* - this call takes care to make sure that the axis provided is a unit vector first
*/
@@ -2051,7 +1942,7 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *o
/* we need to clamp this within sensible values */
// NOTE: these should be fine for now, but should get sanitised in future
- scale= MIN2( MAX2(scale, 0.0001) , 100000);
+ scale= MIN2(MAX2(scale, 0.0001) , 100000);
}
else
scale= 1.0f;
@@ -2072,13 +1963,26 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *o
}
}
- /* step 5: set the location of the bone in the matrix
- * - when the 'no-root' option is affected, the chain can retain
- * the shape but be moved elsewhere
- */
+ /* step 5: set the location of the bone in the matrix */
if (ikData->flag & CONSTRAINT_SPLINEIK_NO_ROOT) {
+ /* when the 'no-root' option is affected, the chain can retain
+ * the shape but be moved elsewhere
+ */
VECCOPY(poseHead, pchan->pose_head);
}
+ else if (tree->con->enforce < 1.0f) {
+ /* when the influence is too low
+ * - blend the positions for the 'root' bone
+ * - stick to the parent for any other
+ */
+ if (pchan->parent) {
+ VECCOPY(poseHead, pchan->pose_head);
+ }
+ else {
+ // FIXME: this introduces popping artifacts when we reach 0.0
+ interp_v3_v3v3(poseHead, pchan->pose_head, poseHead, tree->con->enforce);
+ }
+ }
VECCOPY(poseMat[3], poseHead);
/* finally, store the new transform */
@@ -2110,8 +2014,6 @@ static void splineik_execute_tree(Scene *scene, Object *ob, bPoseChannel *pchan_
splineik_evaluate_bone(tree, scene, ob, pchan, i, ctime);
}
- // TODO: if another pass is needed to ensure the validity of the chain after blending, it should go here
-
/* free the tree info specific to SplineIK trees now */
if (tree->chain) MEM_freeN(tree->chain);
if (tree->free_points) MEM_freeN(tree->points);
@@ -2261,7 +2163,7 @@ static void do_strip_modifiers(Scene *scene, Object *armob, Bone *bone, bPoseCha
nor[0] = BLI_gNoise(amod->noisesize, size[0]+ofs, size[1], size[2], 0, 0) - ofs;
nor[1] = BLI_gNoise(amod->noisesize, size[0], size[1]+ofs, size[2], 0, 0) - ofs;
nor[2] = BLI_gNoise(amod->noisesize, size[0], size[1], size[2]+ofs, 0, 0) - ofs;
- add_v3_v3v3(size, size, nor);
+ add_v3_v3(size, nor);
if (sizeo[0] != 0)
mul_v3_fl(pchan->pose_mat[0], size[0] / sizeo[0]);
@@ -2277,7 +2179,7 @@ static void do_strip_modifiers(Scene *scene, Object *armob, Bone *bone, bPoseCha
nor[2] = BLI_gNoise(amod->noisesize, eul[0], eul[1], eul[2]+ofs, 0, 0) - ofs;
compatible_eul(nor, eulo);
- add_v3_v3v3(eul, eul, nor);
+ add_v3_v3(eul, nor);
compatible_eul(eul, eulo);
loc_eul_size_to_mat4(pchan->pose_mat, loc, eul, size);
@@ -2380,7 +2282,7 @@ void where_is_pose_bone(Scene *scene, Object *ob, bPoseChannel *pchan, float cti
/* only rootbones get the cyclic offset (unless user doesn't want that) */
if ((bone->flag & BONE_NO_CYCLICOFFSET) == 0)
- add_v3_v3v3(pchan->pose_mat[3], pchan->pose_mat[3], ob->pose->cyclic_offset);
+ add_v3_v3(pchan->pose_mat[3], ob->pose->cyclic_offset);
}
if(do_extra) {