diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 7458a0230dd..40bdeff646c 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -181,6 +181,14 @@ void relink_constraints (struct ListBase *list) ID_NEW(data->tar); } break; + case CONSTRAINT_TYPE_SIZELIKE: + { + bSizeLikeConstraint *data; + data = con->data; + + ID_NEW(data->tar); + } + break; case CONSTRAINT_TYPE_FOLLOWPATH: { bFollowPathConstraint *data; @@ -281,6 +289,13 @@ char constraint_has_target (bConstraint *con) return 1; } break; + case CONSTRAINT_TYPE_SIZELIKE: + { + bSizeLikeConstraint *data = con->data; + if (data->tar) + return 1; + } + break; case CONSTRAINT_TYPE_MINMAX: { bMinMaxConstraint *data = con->data; @@ -341,6 +356,12 @@ Object *get_constraint_target(bConstraint *con, char **subtarget) return data->tar; } break; + case CONSTRAINT_TYPE_SIZELIKE: + { + bSizeLikeConstraint *data = con->data; + return data->tar; + } + break; case CONSTRAINT_TYPE_KINEMATIC: { bKinematicConstraint *data = con->data; @@ -418,6 +439,13 @@ void set_constraint_target(bConstraint *con, Object *ob, char *subtarget) if(subtarget) BLI_strncpy(data->subtarget, subtarget, 32); } break; + case CONSTRAINT_TYPE_SIZELIKE: + { + bSizeLikeConstraint *data = con->data; + data->tar= ob; + if(subtarget) BLI_strncpy(data->subtarget, subtarget, 32); + } + break; case CONSTRAINT_TYPE_KINEMATIC: { bKinematicConstraint *data = con->data; @@ -575,6 +603,15 @@ void *new_constraint_data (short type) result = data; } break; + case CONSTRAINT_TYPE_SIZELIKE: + { + bSizeLikeConstraint *data; + data = MEM_callocN(sizeof(bLocateLikeConstraint), "sizelikeConstraint"); + + data->flag |= SIZELIKE_X|SIZELIKE_Y|SIZELIKE_Z; + result = data; + } + break; case CONSTRAINT_TYPE_ACTION: { bActionConstraint *data; @@ -890,6 +927,21 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own Mat4One (mat); } break; + case CONSTRAINT_TYPE_SIZELIKE: + { + bSizeLikeConstraint *data; + data = (bSizeLikeConstraint*)con->data; + + if (data->tar){ + /* Update the location of the target object */ + where_is_object_time (data->tar, ctime); + constraint_target_to_mat4(data->tar, data->subtarget, mat, size, ctime); + valid=1; + } + else + Mat4One (mat); + } + break; case CONSTRAINT_TYPE_TRACKTO: { bTrackToConstraint *data; @@ -1101,6 +1153,24 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype, ob->obmat[2][2] = tmat[2][2]*size[2]; } break; + case CONSTRAINT_TYPE_SIZELIKE: + { + float obsize[3], size[3]; + bSizeLikeConstraint *data; + + data = constraint->data; + + Mat4ToSize(targetmat, size); + Mat4ToSize(ob->obmat, obsize); + + if (data->flag & SIZELIKE_X && obsize[0] != 0) + VecMulf(ob->obmat[0], size[0] / obsize[0]); + if (data->flag & SIZELIKE_Y && obsize[1] != 0) + VecMulf(ob->obmat[1], size[1] / obsize[1]); + if (data->flag & SIZELIKE_Z && obsize[2] != 0) + VecMulf(ob->obmat[2], size[2] / obsize[2]); + } + break; case CONSTRAINT_TYPE_NULL: { } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index ba532cfdfe3..a688effe8a7 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -1399,6 +1399,13 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist) data->tar = newlibadr(fd, id->lib, data->tar); }; break; + case CONSTRAINT_TYPE_SIZELIKE: + { + bSizeLikeConstraint *data; + data= ((bSizeLikeConstraint*)con->data); + data->tar = newlibadr(fd, id->lib, data->tar); + }; + break; case CONSTRAINT_TYPE_KINEMATIC: { bKinematicConstraint *data; @@ -5719,6 +5726,12 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb) expand_doit(fd, mainvar, data->tar); break; } + case CONSTRAINT_TYPE_SIZELIKE: + { + bSizeLikeConstraint *data = (bSizeLikeConstraint*)curcon->data; + expand_doit(fd, mainvar, data->tar); + break; + } case CONSTRAINT_TYPE_KINEMATIC: { bKinematicConstraint *data = (bKinematicConstraint*)curcon->data; diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index cb2abd71ca0..c1d8eda9007 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -647,6 +647,9 @@ static void write_constraints(WriteData *wd, ListBase *conlist) case CONSTRAINT_TYPE_LOCLIKE: writestruct(wd, DATA, "bLocateLikeConstraint", 1, con->data); break; + case CONSTRAINT_TYPE_SIZELIKE: + writestruct(wd, DATA, "bSizeLikeConstraint", 1, con->data); + break; case CONSTRAINT_TYPE_ACTION: writestruct(wd, DATA, "bActionConstraint", 1, con->data); break; diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index 999213083ca..82c9756f2b3 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -591,6 +591,7 @@ enum { B_CONSTRAINT_ADD_MINMAX, B_CONSTRAINT_ADD_ROTLIKE, B_CONSTRAINT_ADD_LOCLIKE, + B_CONSTRAINT_ADD_SIZELIKE, B_CONSTRAINT_ADD_ACTION, B_CONSTRAINT_ADD_LOCKTRACK, B_CONSTRAINT_ADD_FOLLOWPATH, diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index cf1c5101407..b7dcadd501c 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -105,6 +105,13 @@ typedef struct bMinMaxConstraint{ char subtarget[32]; } bMinMaxConstraint; +typedef struct bSizeLikeConstraint{ + Object *tar; + int flag; + int reserved1; + char subtarget[32]; +} bSizeLikeConstraint; + typedef struct bActionConstraint{ Object *tar; short type; @@ -174,7 +181,7 @@ typedef struct bStretchToConstraint{ #define CONSTRAINT_TYPE_SIZELIMIT 7 /* Unimplemented */ #define CONSTRAINT_TYPE_ROTLIKE 8 #define CONSTRAINT_TYPE_LOCLIKE 9 -#define CONSTRAINT_TYPE_SIZELIKE 10 /* Unimplemented */ +#define CONSTRAINT_TYPE_SIZELIKE 10 #define CONSTRAINT_TYPE_PYTHON 11 /* Unimplemented */ #define CONSTRAINT_TYPE_ACTION 12 #define CONSTRAINT_TYPE_LOCKTRACK 13 /* New Tracking constraint that locks an axis in place - theeth */ @@ -208,6 +215,12 @@ typedef struct bStretchToConstraint{ #define LOCLIKE_Y 0x02 #define LOCLIKE_Z 0x04 #define LOCSPACE 0x08 + +/* bSizeLikeConstraint.flag */ +#define SIZELIKE_X 0x01 +#define SIZELIKE_Y 0x02 +#define SIZELIKE_Z 0x04 +#define SIZESPACE 0x08 /* Axis flags */ #define LOCK_X 0x00 diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index a6906af245d..9f43e06926c 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -334,6 +334,9 @@ static void get_constraint_typestring (char *str, bConstraint *con) case CONSTRAINT_TYPE_LOCLIKE: strcpy (str, "Copy Location"); return; + case CONSTRAINT_TYPE_SIZELIKE: + strcpy (str, "Copy Size"); + return; case CONSTRAINT_TYPE_ACTION: strcpy (str, "Action"); return; @@ -367,6 +370,8 @@ static int get_constraint_col(bConstraint *con) return TH_BUT_POPUP; case CONSTRAINT_TYPE_MINMAX: return TH_BUT_POPUP; + case CONSTRAINT_TYPE_SIZELIKE: + return TH_BUT_POPUP; case CONSTRAINT_TYPE_ACTION: return TH_BUT_ACTION; case CONSTRAINT_TYPE_LOCKTRACK: @@ -686,6 +691,38 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s uiBlockEndAlign(block); } break; + case CONSTRAINT_TYPE_SIZELIKE: + { + bSizeLikeConstraint *data = con->data; + bArmature *arm; + height = 66; + + BIF_ThemeColor(curCol); + glRects(*xco+3, *yco-height-39, *xco+width+30, *yco-18); + + 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 */ + uiBlockBeginAlign(block); + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); + + arm = get_armature(data->tar); + if (arm){ + but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone"); + uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar); + } + else + strcpy (data->subtarget, ""); + uiBlockEndAlign(block); + + /* Draw XYZ toggles */ + uiBlockBeginAlign(block); + but=uiDefButI(block, TOG|BIT|0, B_CONSTRAINT_TEST, "X", *xco+((width/2)-48), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy X component"); + but=uiDefButI(block, TOG|BIT|1, B_CONSTRAINT_TEST, "Y", *xco+((width/2)-16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Y component"); + but=uiDefButI(block, TOG|BIT|2, B_CONSTRAINT_TEST, "Z", *xco+((width/2)+16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Z component"); + uiBlockEndAlign(block); + } + break; case CONSTRAINT_TYPE_KINEMATIC: { bKinematicConstraint *data = con->data; @@ -977,6 +1014,7 @@ static uiBlock *add_constraintmenu(void *arg_unused) uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCLIKE,"Copy Location", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, ""); uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ROTLIKE,"Copy Rotation", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, ""); + uiDefBut(block, BUTM, B_CONSTRAINT_ADD_SIZELIKE,"Copy Size", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, ""); uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, ""); @@ -1083,6 +1121,16 @@ void do_constraintbuts(unsigned short event) BIF_undo_push("Add constraint"); } break; + case B_CONSTRAINT_ADD_SIZELIKE: + { + bConstraint *con; + + con = add_new_constraint(CONSTRAINT_TYPE_SIZELIKE); + add_constraint_to_active(ob, con); + + BIF_undo_push("Add constraint"); + } + break; case B_CONSTRAINT_ADD_ACTION: { bConstraint *con; diff --git a/source/blender/src/editconstraint.c b/source/blender/src/editconstraint.c index a85f0dd835d..b3f2ac07c0b 100644 --- a/source/blender/src/editconstraint.c +++ b/source/blender/src/editconstraint.c @@ -266,6 +266,12 @@ char *get_con_subtarget_name(bConstraint *con, Object *target) if (data->tar==target) return data->subtarget; } break; + case CONSTRAINT_TYPE_SIZELIKE: + { + bSizeLikeConstraint *data = con->data; + if (data->tar==target) return data->subtarget; + } + break; case CONSTRAINT_TYPE_KINEMATIC: { bKinematicConstraint *data = con->data; @@ -428,6 +434,24 @@ static void test_constraints (Object *owner, const char* substring) break; } + if ( (data->tar == owner) && + (!get_named_bone(get_armature(owner), + data->subtarget))) { + curcon->flag |= CONSTRAINT_DISABLE; + break; + } + } + break; + case CONSTRAINT_TYPE_SIZELIKE: + { + bSizeLikeConstraint *data = curcon->data; + + if (!exist_object(data->tar)){ + data->tar = NULL; + curcon->flag |= CONSTRAINT_DISABLE; + break; + } + if ( (data->tar == owner) && (!get_named_bone(get_armature(owner), data->subtarget))) { @@ -629,21 +653,21 @@ void add_constraint(int only_IK) else { if(pchanact) { if(pchansel) - nr= pupmenu("Add Constraint to Active Bone%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7"); + nr= pupmenu("Add Constraint to Active Bone%t|Copy Location%x1|Copy Rotation%x2|Copy Size%x8|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7"); else if(obsel && obsel->type==OB_CURVE) - nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Stretch To%x7"); + nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Copy Size%x8|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Stretch To%x7"); else if(obsel) - nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7"); + nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Copy Size%x8|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7"); else - nr= pupmenu("Add Constraint to New Empty Object%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7"); + nr= pupmenu("Add Constraint to New Empty Object%t|Copy Location%x1|Copy Rotation%x2|Copy Size%x8|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7"); } else { if(obsel && obsel->type==OB_CURVE) - nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6"); + nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Copy Size%x8|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6"); else if(obsel) - nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5"); + nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Copy Size%x8|Track To%x3|Floor%x4|Locked Track%x5"); else - nr= pupmenu("Add Constraint to New Empty Object%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5"); + nr= pupmenu("Add Constraint to New Empty Object%t|Copy Location%x1|Copy Rotation%x2|Copy Size%x8|Track To%x3|Floor%x4|Locked Track%x5"); } } @@ -689,6 +713,7 @@ void add_constraint(int only_IK) else if(nr==5) con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK); else if(nr==6) con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH); else if(nr==7) con = add_new_constraint(CONSTRAINT_TYPE_STRETCHTO); + else if(nr==8) con = add_new_constraint(CONSTRAINT_TYPE_SIZELIKE); if(con==NULL) return; /* paranoia */