Path: [ #2789 ] Add a "copy size" constraint

At long last!
This new constraint is pretty simple. Following in the footsteps of such giants as Copy Loc and Copy Rot, it lets you constrain the size of an object/bone to another object/bone, with per axis restrictions.
This commit is contained in:
Martin Poirier 2006-02-19 17:42:20 +00:00
parent c7b472a54e
commit da6b87abb1
7 changed files with 181 additions and 8 deletions

View File

@ -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:
{
}

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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

View File

@ -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;

View File

@ -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 */