Commit: a26d1a64e4504c1bd2b136f5a12405c503b5c7e3 Author: Sergey Sharybin Date: Wed Feb 4 16:15:55 2015 +0500 Branches: depsgraph_refactor https://developer.blender.org/rBa26d1a64e4504c1bd2b136f5a12405c503b5c7e3
Merge branch 'master' into depsgraph_refactor Conflicts: source/blender/blenkernel/intern/armature.c source/blender/modifiers/intern/MOD_hook.c =================================================================== =================================================================== diff --cc source/blender/blenkernel/intern/armature_update.c index 3981ad5,0000000..4344c56 mode 100644,000000..100644 --- a/source/blender/blenkernel/intern/armature_update.c +++ b/source/blender/blenkernel/intern/armature_update.c @@@ -1,709 -1,0 +1,709 @@@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2015 Blender Foundation. + * All rights reserved. + * + * Original Author: Joshua Leung + * Contributor(s): None Yet + * + * ***** END GPL LICENSE BLOCK ***** + * + * Defines and code for core node types + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_listbase.h" +#include "BLI_math.h" + +#include "DNA_armature_types.h" +#include "DNA_constraint_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "BKE_anim.h" +#include "BKE_armature.h" +#include "BKE_curve.h" +#include "BKE_depsgraph.h" +#include "BKE_displist.h" +#include "BKE_fcurve.h" +#include "BKE_scene.h" + +#include "BIK_api.h" + +#include "BKE_global.h" +#include "BKE_main.h" + +#include "DEG_depsgraph.h" + +#ifdef WITH_LEGACY_DEPSGRAPH +# define DEBUG_PRINT if (!DEG_depsgraph_use_legacy() && G.debug & G_DEBUG_DEPSGRAPH) printf +#else +# define DEBUG_PRINT if (G.debug & G_DEBUG_DEPSGRAPH) printf +#endif + +/* ********************** SPLINE IK SOLVER ******************* */ + +/* Temporary evaluation tree data used for Spline IK */ +typedef struct tSplineIK_Tree { + struct tSplineIK_Tree *next, *prev; + + int type; /* type of IK that this serves (CONSTRAINT_TYPE_KINEMATIC or ..._SPLINEIK) */ + + bool free_points; /* free the point positions array */ + short chainlen; /* number of bones in the chain */ + + float *points; /* parametric positions for the joints along the curve */ + bPoseChannel **chain; /* chain of bones to affect using Spline IK (ordered from the tip) */ + + bPoseChannel *root; /* bone that is the root node of the chain */ + + bConstraint *con; /* constraint for this chain */ + bSplineIKConstraint *ikData; /* constraint settings for this chain */ +} tSplineIK_Tree; + +/* ----------- */ + +/* Tag the bones in the chain formed by the given bone for IK */ +static void splineik_init_tree_from_pchan(Scene *scene, Object *UNUSED(ob), bPoseChannel *pchan_tip) +{ + bPoseChannel *pchan, *pchanRoot = NULL; + bPoseChannel *pchanChain[255]; + bConstraint *con = NULL; + bSplineIKConstraint *ikData = NULL; + float boneLengths[255], *jointPoints; + float totLength = 0.0f; + bool free_joints = 0; + int segcount = 0; + + /* find the SplineIK constraint */ + for (con = pchan_tip->constraints.first; con; con = con->next) { + if (con->type == CONSTRAINT_TYPE_SPLINEIK) { + ikData = con->data; + + /* target can only be curve */ + if ((ikData->tar == NULL) || (ikData->tar->type != OB_CURVE)) + continue; + /* skip if disabled */ + if ((con->enforce == 0.0f) || (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF))) + continue; + + /* otherwise, constraint is ok... */ + break; + } + } + if (con == NULL) + return; + + /* make sure that the constraint targets are ok + * - this is a workaround for a depsgraph bug... + */ + if (ikData->tar) { + /* note: when creating constraints that follow path, the curve gets the CU_PATH set now, + * currently for paths to work it needs to go through the bevlist/displist system (ton) + */ + + /* only happens on reload file, but violates depsgraph still... fix! */ + if (ELEM(NULL, ikData->tar->curve_cache, ikData->tar->curve_cache->path, ikData->tar->curve_cache->path->data)) { + BKE_displist_make_curveTypes(scene, ikData->tar, 0); + + /* path building may fail in EditMode after removing verts [#33268]*/ + if (ELEM(NULL, ikData->tar->curve_cache->path, ikData->tar->curve_cache->path->data)) { + /* BLI_assert(cu->path != NULL); */ + return; + } + } + } + + /* 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 && (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]; + } + + if (segcount == 0) + return; + else + pchanRoot = pchanChain[segcount - 1]; + + /* perform binding step if required */ + if ((ikData->flag & CONSTRAINT_SPLINEIK_BOUND) == 0) { + float segmentLen = (1.0f / (float)segcount); + int i; + + /* setup new empty array for the points list */ + if (ikData->points) + MEM_freeN(ikData->points); + ikData->numpoints = ikData->chainlen + 1; + ikData->points = MEM_mallocN(sizeof(float) * ikData->numpoints, "Spline IK Binding"); + + /* bind 'tip' of chain (i.e. first joint = tip of bone with the Spline IK Constraint) */ + ikData->points[0] = 1.0f; + + /* perform binding of the joints to parametric positions along the curve based + * proportion of the total length that each bone occupies + */ + for (i = 0; i < segcount; i++) { + /* 'head' joints, traveling towards the root of the chain + * - 2 methods; the one chosen depends on whether we've got usable lengths + */ + if ((ikData->flag & CONSTRAINT_SPLINEIK_EVENSPLITS) || (totLength == 0.0f)) { + /* 1) equi-spaced joints */ + ikData->points[i + 1] = ikData->points[i] - segmentLen; + } + else { + /* 2) to find this point on the curve, we take a step from the previous joint + * a distance given by the proportion that this bone takes + */ + ikData->points[i + 1] = ikData->points[i] - (boneLengths[i] / totLength); + } + } + + /* spline has now been bound */ + ikData->flag |= CONSTRAINT_SPLINEIK_BOUND; + } + + /* disallow negative values (happens with float precision) */ + CLAMP_MIN(ikData->points[segcount], 0.0f); + + /* apply corrections for sensitivity to scaling on a copy of the bind points, + * since it's easier to determine the positions of all the joints beforehand this way + */ + if ((ikData->flag & CONSTRAINT_SPLINEIK_SCALE_LIMITED) && (totLength != 0.0f)) { + float splineLen, maxScale; + int i; + + /* make a copy of the points array, that we'll store in the tree + * - although we could just multiply the points on the fly, this approach means that + * we can introduce per-segment stretchiness later if it is necessary + */ + jointPoints = MEM_dupallocN(ikData->points); + free_joints = 1; + + /* get the current length of the curve */ + /* NOTE: this is assumed to be correct even after the curve was resized */ + splineLen = ikData->tar->curve_cache->path->totdist; + + /* calculate the scale factor to multiply all the path values by so that the + * bone chain retains its current length, such that + * maxScale * splineLen = totLength + */ + maxScale = totLength / splineLen; + + /* apply scaling correction to all of the temporary points */ + /* TODO: this is really not adequate enough on really short chains */ + for (i = 0; i < segcount; i++) + jointPoints[i] *= maxScale; + } + else { + /* just use the existing points array */ + jointPoints = ikData->points; + free_joints = 0; + } + + /* make a new Spline-IK chain, and store it in the IK chains */ + /* TODO: we should check if there is already an IK chain on this, since that would take presidence... */ + { + /* make new tree */ + tSplineIK_Tree *tree = MEM_callocN(sizeof(tSplineIK_Tree), "SplineIK Tree"); + tree->type = CONSTRAINT_TYPE_SPLINEIK; + + tree->chainlen = segcount; + + /* copy over the array of links to bones in the chain (from tip to root) */ + tree->chain = MEM_mallocN(sizeof(bPoseChannel *) * segcount, "SplineIK Chain"); + memcpy(tree->chain, pchanChain, sizeof(bPoseChannel *) * segcount); + + /* store reference to joint position array */ + tree->points = jointPoints; + tree->free_points = free_joints; + + /* store references to different parts of the chain */ + tree->root = pchanRoot; + tree->con = con; + tree->ikData = ikData; + + /* AND! link the tree to the root */ + BLI_addtail(&pchanRoot->siktree, tree); + } + + /* mark root channel having an IK tree */ + pchanRoot->flag |= POSE_IKSPLINE; +} + +/* Tag which bones are members of Spline IK chains */ +static void splineik_init_tree(Scene *scene, Object *ob, float UNUSED(ctime)) +{ + bPoseChannel *pchan; + + /* find the tips of Spline IK chains, which are simply the bones which have been tagged as such */ + for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + if (pchan->constflag & PCHAN_HAS_SPLINEIK) + splineik_init_tree_from_pchan(scene, ob, pchan); + } +} + +/* ----------- */ + +/* Evaluate spline IK for a given bone */ +static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *ob, bPoseChannel *pchan, + int index, float ctime) +{ + bSplineIKConstraint *ikData = tree->ikData; + float poseHead[3], poseTail[3], poseMat[4][4]; + float splineVec[3], scaleFac, radius = 1.0f; + + /* firstly, calculate the @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs