diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 63 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_constraint_types.h | 5 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Constraint.c | 8 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/Constraint.py | 1 | ||||
-rw-r--r-- | source/blender/src/buttons_object.c | 10 |
5 files changed, 71 insertions, 16 deletions
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 4f79e6867b9..8445fe88797 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -2599,7 +2599,7 @@ static void evaluate_constraint (bConstraint *constraint, float ownermat[][4], f /* find best position on curve */ /* 1. determine which axis to sample on? */ - if (data->flag==CLAMPTO_AUTO) { + if (data->flag == CLAMPTO_AUTO) { float size[3]; VecSubf(size, curveMax, curveMin); @@ -2608,23 +2608,60 @@ static void evaluate_constraint (bConstraint *constraint, float ownermat[][4], f * frequently used. */ if ((size[2]>size[0]) && (size[2]>size[1])) - clamp_axis= CLAMPTO_Z; + clamp_axis= CLAMPTO_Z - 1; else if ((size[1]>size[0]) && (size[1]>size[2])) - clamp_axis= CLAMPTO_Y; + clamp_axis= CLAMPTO_Y - 1; else - clamp_axis = CLAMPTO_X; + clamp_axis = CLAMPTO_X - 1; } else - clamp_axis= data->flag; + clamp_axis= data->flag - 1; - /* 2. determine position relative to curve on a 0-1 scale */ - if (clamp_axis > 0) clamp_axis--; - if (ownLoc[clamp_axis] <= curveMin[clamp_axis]) - curvetime = 0.0; - else if (ownLoc[clamp_axis] >= curveMax[clamp_axis]) - curvetime = 1.0; - else - curvetime = (ownLoc[clamp_axis] - curveMin[clamp_axis]) / (curveMax[clamp_axis] - curveMin[clamp_axis]); + /* 2. determine position relative to curve on a 0-1 scale based on bounding box */ + if (data->flag2 & CLAMPTO_CYCLIC) { + /* cyclic, so offset within relative bounding box is used */ + float len= (curveMax[clamp_axis] - curveMin[clamp_axis]); + float offset; + + /* find bounding-box range where target is located */ + if (ownLoc[clamp_axis] < curveMin[clamp_axis]) { + /* bounding-box range is before */ + offset= curveMin[clamp_axis]; + + while (ownLoc[clamp_axis] < offset) + offset -= len; + + /* now, we calculate as per normal, except using offset instead of curveMin[clamp_axis] */ + curvetime = (ownLoc[clamp_axis] - offset) / (len); + } + else if (ownLoc[clamp_axis] > curveMax[clamp_axis]) { + /* bounding-box range is after */ + offset= curveMax[clamp_axis]; + + while (ownLoc[clamp_axis] > offset) { + if ((offset + len) > ownLoc[clamp_axis]) + break; + else + offset += len; + } + + /* now, we calculate as per normal, except using offset instead of curveMax[clamp_axis] */ + curvetime = (ownLoc[clamp_axis] - offset) / (len); + } + else { + /* as the location falls within bounds, just calculate */ + curvetime = (ownLoc[clamp_axis] - curveMin[clamp_axis]) / (len); + } + } + else { + /* no cyclic, so position is clamped to within the bounding box */ + if (ownLoc[clamp_axis] <= curveMin[clamp_axis]) + curvetime = 0.0; + else if (ownLoc[clamp_axis] >= curveMax[clamp_axis]) + curvetime = 1.0; + else + curvetime = (ownLoc[clamp_axis] - curveMin[clamp_axis]) / (curveMax[clamp_axis] - curveMin[clamp_axis]); + } /* 3. position on curve */ if(where_on_path(data->tar, curvetime, vec, dir) ) { diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index 9a0d5a095e5..fcde95371ac 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -205,7 +205,7 @@ typedef struct bRigidBodyJointConstraint { typedef struct bClampToConstraint { Object *tar; /* 'target' must be a curve */ int flag; /* which axis/plane to compare owner's location on */ - int pad; + int flag2; /* for legacy reasons, this is flag2. used for any extra settings */ } bClampToConstraint; /* Child Of Constraint */ @@ -373,6 +373,9 @@ typedef struct bSizeLimitConstraint { #define CLAMPTO_Y 2 #define CLAMPTO_Z 3 +/* ClampTo Constraint ->flag2 */ +#define CLAMPTO_CYCLIC 1 + /* bKinematicConstraint->flag */ #define CONSTRAINT_IK_TIP 1 #define CONSTRAINT_IK_ROT 2 diff --git a/source/blender/python/api2_2x/Constraint.c b/source/blender/python/api2_2x/Constraint.c index 0e235082c61..4dddd274a0e 100644 --- a/source/blender/python/api2_2x/Constraint.c +++ b/source/blender/python/api2_2x/Constraint.c @@ -125,6 +125,8 @@ enum constraint_constants { EXPP_CONSTR_LIMYROT = LIMIT_YROT, EXPP_CONSTR_LIMZROT = LIMIT_ZROT, + EXPP_CONSTR_CLAMPCYCLIC, + EXPP_CONSTR_XMIN, EXPP_CONSTR_XMAX, EXPP_CONSTR_YMIN, @@ -887,6 +889,8 @@ static PyObject *clampto_getter( BPy_Constraint * self, int type ) return Object_CreatePyObject( con->tar ); case EXPP_CONSTR_CLAMP: return PyInt_FromLong( (long)con->flag ); + case EXPP_CONSTR_CLAMPCYCLIC: + return PyBool_FromLong( (long)(con->flag2 & CLAMPTO_CYCLIC) ); default: return EXPP_ReturnPyObjError( PyExc_KeyError, "key not found" ); } @@ -908,6 +912,8 @@ static int clampto_setter( BPy_Constraint *self, int type, PyObject *value ) case EXPP_CONSTR_CLAMP: return EXPP_setIValueRange( value, &con->flag, CLAMPTO_AUTO, CLAMPTO_Z, 'i' ); + case EXPP_CONSTR_CLAMPCYCLIC: + return EXPP_setBitfield( value, &con->flag2, CLAMPTO_CYCLIC, 'i' ); default: return EXPP_ReturnIntError( PyExc_KeyError, "key not found" ); } @@ -2418,6 +2424,8 @@ static PyObject *M_Constraint_SettingsDict( void ) PyInt_FromLong( CLAMPTO_Y ) ); PyConstant_Insert( d, "CLAMPZ", PyInt_FromLong( CLAMPTO_Z ) ); + PyConstant_Insert( d, "CLAMPCYCLIC", + PyInt_FromLong( EXPP_CONSTR_CLAMPCYCLIC )); PyConstant_Insert( d, "TARGET", PyInt_FromLong( EXPP_CONSTR_TARGET ) ); diff --git a/source/blender/python/api2_2x/doc/Constraint.py b/source/blender/python/api2_2x/doc/Constraint.py index bb81d2cba7a..4c1981c5238 100644 --- a/source/blender/python/api2_2x/doc/Constraint.py +++ b/source/blender/python/api2_2x/doc/Constraint.py @@ -86,6 +86,7 @@ Or to print all the constraints attached to each bone in a pose:: - LOCK (int): values are LOCKX, LOCKY, LOCKZ - Used by Clamp To (CLAMPTO) constraint: - CLAMP (int): values are CLAMPAUTO, CLAMPX, CLAMPY, CLAMPZ + - CLAMPCYCLIC (bool) - Used by Floor (FLOOR) constraint: - MINMAX (int): values are MINX, MINY, MINZ, MAXX, MAXY, MAXZ - OFFSET (float): clamped to [-100.0,100.0] diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 033a7dc18cc..cd3246fcd8d 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -1409,11 +1409,11 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s { bClampToConstraint *data = con->data; - height = 66; + height = 90; uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); - + /* Draw target parameters */ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); @@ -1425,6 +1425,12 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s uiDefButI(block, ROW, B_CONSTRAINT_TEST, "Y", *xco+182, *yco-64, 32, 18, &data->flag, 12.0, CLAMPTO_Y, 0, 0, "Main axis of movement is y-axis"); uiDefButI(block, ROW, B_CONSTRAINT_TEST, "Z", *xco+214, *yco-64, 32, 18, &data->flag, 12.0, CLAMPTO_Z, 0, 0, "Main axis of movement is z-axis"); uiBlockEndAlign(block); + + /* Extra Options Controlling Behaviour */ + uiBlockBeginAlign(block); + uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Options:", *xco, *yco-86, 90, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); + uiDefButBitI(block, TOG, CLAMPTO_CYCLIC, B_CONSTRAINT_TEST, "Cyclic", *xco+((width/2)), *yco-86,60,19, &data->flag2, 0, 0, 0, 0, "Treat curve as cyclic curve (no clamping to curve bounding box)"); + uiBlockEndAlign(block); } break; case CONSTRAINT_TYPE_TRANSFORM: |