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:
-rw-r--r--source/blender/blenkernel/intern/constraint.c116
-rw-r--r--source/blender/blenloader/intern/readfile.c14
-rw-r--r--source/blender/include/butspace.h2
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h25
-rw-r--r--source/blender/src/buttons_object.c57
-rw-r--r--source/blender/src/editconstraint.c15
-rw-r--r--source/blender/src/editipo.c2
7 files changed, 219 insertions, 12 deletions
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 7d7180da271..38f25b54fd8 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -2382,6 +2382,118 @@ static bConstraintTypeInfo CTI_LOCKTRACK = {
locktrack_evaluate /* evaluate */
};
+/* ---------- Limit Distance Constraint ----------- */
+
+static void distlimit_new_data (void *cdata)
+{
+ bDistLimitConstraint *data= (bDistLimitConstraint *)cdata;
+
+ data->dist= 0.0;
+}
+
+static void distlimit_get_tars (bConstraint *con, ListBase *list)
+{
+ if (con && list) {
+ bDistLimitConstraint *data= con->data;
+ bConstraintTarget *ct;
+
+ /* standard target-getting macro for single-target constraints */
+ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
+ }
+}
+
+static void distlimit_flush_tars (bConstraint *con, ListBase *list, short nocopy)
+{
+ if (con && list) {
+ bDistLimitConstraint *data= con->data;
+ bConstraintTarget *ct= list->first;
+
+ /* the following macro is used for all standard single-target constraints */
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
+ }
+}
+
+static void distlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
+{
+ bDistLimitConstraint *data= con->data;
+ bConstraintTarget *ct= targets->first;
+
+ /* only evaluate if there is a target */
+ if (VALID_CONS_TARGET(ct)) {
+ float dvec[3], dist=0.0f, sfac=1.0f;
+ short clamp_surf= 0;
+
+ /* calculate our current distance from the target */
+ dist= VecLenf(cob->matrix[3], ct->matrix[3]);
+
+ /* set distance (flag is only set when user demands it) */
+ if (data->dist == 0)
+ data->dist= dist;
+
+ /* check if we're which way to clamp from, and calculate interpolation factor (if needed) */
+ if (data->mode == LIMITDIST_OUTSIDE) {
+ /* if inside, then move to surface */
+ if (dist <= data->dist) {
+ clamp_surf= 1;
+ sfac= data->dist / dist;
+ }
+ /* if soft-distance is enabled, start fading once owner is dist+softdist from the target */
+ else if (data->flag & LIMITDIST_USESOFT) {
+ if (dist <= (data->dist + data->soft)) {
+
+ }
+ }
+ }
+ else if (data->mode == LIMITDIST_INSIDE) {
+ /* if outside, then move to surface */
+ if (dist >= data->dist) {
+ clamp_surf= 1;
+ sfac= data->dist / dist;
+ }
+ /* if soft-distance is enabled, start fading once owner is dist-soft from the target */
+ else if (data->flag & LIMITDIST_USESOFT) {
+ // FIXME: there's a problem with "jumping" when this kicks in
+ if (dist >= (data->dist - data->soft)) {
+ sfac = data->soft*(1.0 - exp(-(dist - data->dist)/data->soft)) + data->dist;
+ sfac /= dist;
+
+ clamp_surf= 1;
+ }
+ }
+ }
+ else {
+ if (IS_EQ(dist, data->dist)==0) {
+ clamp_surf= 1;
+ sfac= data->dist / dist;
+ }
+ }
+
+ /* clamp to 'surface' (i.e. move owner so that dist == data->dist) */
+ if (clamp_surf) {
+ /* simply interpolate along line formed by target -> owner */
+ VecLerpf(dvec, ct->matrix[3], cob->matrix[3], sfac);
+
+ /* copy new vector onto owner */
+ VECCOPY(cob->matrix[3], dvec);
+ }
+ }
+}
+
+static bConstraintTypeInfo CTI_DISTLIMIT = {
+ CONSTRAINT_TYPE_DISTLIMIT, /* type */
+ sizeof(bDistLimitConstraint), /* size */
+ "Limit Distance", /* name */
+ "bDistLimitConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ NULL, /* copy data */
+ distlimit_new_data, /* new data */
+ distlimit_get_tars, /* get constraint targets */
+ distlimit_flush_tars, /* flush constraint targets */
+ default_get_tarmat, /* get a target matrix */
+ distlimit_evaluate /* evaluate */
+};
+
/* ---------- Stretch To ------------ */
static void stretchto_new_data (void *cdata)
@@ -3067,12 +3179,12 @@ static void constraints_init_typeinfo () {
constraintsTypeInfo[11]= &CTI_PYTHON; /* Python/Script Constraint */
constraintsTypeInfo[12]= &CTI_ACTION; /* Action Constraint */
constraintsTypeInfo[13]= &CTI_LOCKTRACK; /* Locked-Track Constraint */
- constraintsTypeInfo[14]= NULL; /* 'Distance Limit' Constraint */
+ constraintsTypeInfo[14]= &CTI_DISTLIMIT; /* Limit Distance Constraint */
constraintsTypeInfo[15]= &CTI_STRETCHTO; /* StretchTo Constaint */
constraintsTypeInfo[16]= &CTI_MINMAX; /* Floor Constraint */
constraintsTypeInfo[17]= &CTI_RIGIDBODYJOINT; /* RigidBody Constraint */
constraintsTypeInfo[18]= &CTI_CLAMPTO; /* ClampTo Constraint */
- constraintsTypeInfo[19]= &CTI_TRANSFORM; /* Transformation Constraint */
+ constraintsTypeInfo[19]= &CTI_TRANSFORM; /* Transformation Constraint */
}
/* This function should be used for getting the appropriate type-info when only
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 8481e7c0a3a..f3a3a3478ac 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -1752,6 +1752,13 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
data->tar = newlibadr(fd, id->lib, data->tar);
}
break;
+ case CONSTRAINT_TYPE_DISTLIMIT:
+ {
+ bDistLimitConstraint *data;
+ data= ((bDistLimitConstraint*)con->data);
+ data->tar = newlibadr(fd, id->lib, data->tar);
+ }
+ break;
case CONSTRAINT_TYPE_NULL:
break;
}
@@ -1765,6 +1772,7 @@ static void direct_link_constraints(FileData *fd, ListBase *lb)
link_list(fd, lb);
for (cons=lb->first; cons; cons=cons->next) {
cons->data = newdataadr(fd, cons->data);
+
if (cons->type == CONSTRAINT_TYPE_PYTHON) {
bPythonConstraint *data= cons->data;
link_list(fd, &data->targets);
@@ -7807,6 +7815,12 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb)
expand_doit(fd, mainvar, data->tar);
}
break;
+ case CONSTRAINT_TYPE_DISTLIMIT:
+ {
+ bDistLimitConstraint *data = (bDistLimitConstraint*)curcon->data;
+ expand_doit(fd, mainvar, data->tar);
+ }
+ break;
default:
break;
}
diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h
index 6d7a73eec54..a067b3e1489 100644
--- a/source/blender/include/butspace.h
+++ b/source/blender/include/butspace.h
@@ -694,7 +694,7 @@ enum {
B_CONSTRAINT_ADD_ACTION,
B_CONSTRAINT_ADD_LOCKTRACK,
B_CONSTRAINT_ADD_FOLLOWPATH,
- B_CONSTRAINT_ADD_DISTANCELIMIT,
+ B_CONSTRAINT_ADD_DISTLIMIT,
B_CONSTRAINT_ADD_STRETCHTO,
B_CONSTRAINT_ADD_LOCLIMIT,
B_CONSTRAINT_ADD_ROTLIMIT,
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index 4ae8d6b39e6..2bcf2412588 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -307,6 +307,19 @@ typedef struct bSizeLimitConstraint {
short flag2;
} bSizeLimitConstraint;
+/* Limit Distance Constraint */
+typedef struct bDistLimitConstraint {
+ Object *tar;
+ char subtarget[32];
+
+ float dist; /* distance (radius of clamping sphere) from target */
+ float soft; /* distance from clamping-sphere to start applying 'fade' */
+
+ short flag; /* settings */
+ short mode; /* how to limit in relation to clamping sphere */
+ int pad;
+} bDistLimitConstraint;
+
/* ------------------------------------------ */
/* bConstraint->type
@@ -328,13 +341,14 @@ typedef enum B_CONSTAINT_TYPES {
CONSTRAINT_TYPE_PYTHON, /* Unimplemented no longer :) - Aligorith. Scripts */
CONSTRAINT_TYPE_ACTION,
CONSTRAINT_TYPE_LOCKTRACK, /* New Tracking constraint that locks an axis in place - theeth */
- CONSTRAINT_TYPE_DISTANCELIMIT, /* was never properly coded - removed! */
+ CONSTRAINT_TYPE_DISTLIMIT, /* limit distance */
CONSTRAINT_TYPE_STRETCHTO, /* claiming this to be mine :) is in tuhopuu bjornmose */
CONSTRAINT_TYPE_MINMAX, /* floor constraint */
CONSTRAINT_TYPE_RIGIDBODYJOINT, /* rigidbody constraint */
CONSTRAINT_TYPE_CLAMPTO, /* clampto constraint */
CONSTRAINT_TYPE_TRANSFORM, /* transformation (loc/rot/size -> loc/rot/size) constraint */
+
/* NOTE: everytime a new constraint is added, update this */
NUM_CONSTRAINT_TYPES= CONSTRAINT_TYPE_TRANSFORM
} B_CONSTRAINT_TYPES;
@@ -478,6 +492,15 @@ typedef enum B_CONSTRAINTCHANNEL_FLAG {
#define LIMIT_NOPARENT 0x01
/* for all Limit constraints - allow to be used during transform? */
#define LIMIT_TRANSFORM 0x02
+
+/* distance limit constraint */
+ /* bDistLimitConstraint->flag */
+#define LIMITDIST_USESOFT (1<<0)
+
+ /* bDistLimitConstraint->mode */
+#define LIMITDIST_INSIDE 0
+#define LIMITDIST_OUTSIDE 1
+#define LIMITDIST_ONSURFACE 2
/* python constraint -> flag */
#define PYCON_USETARGETS 0x01
diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c
index 1a415b461cb..32218c27ace 100644
--- a/source/blender/src/buttons_object.c
+++ b/source/blender/src/buttons_object.c
@@ -1439,6 +1439,54 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
draw_constraint_spaceselect(block, con, *xco, *yco-130, is_armature_owner(ob), -1);
}
break;
+ case CONSTRAINT_TYPE_DISTLIMIT:
+ {
+ bDistLimitConstraint *data = con->data;
+
+ height = 105;
+ 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 */
+ uiBlockBeginAlign(block);
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object");
+
+ if (is_armature_target(data->tar)) {
+ 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 if (is_geom_target(data->tar)) {
+ but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
+ uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
+ }
+ else {
+ strcpy(data->subtarget, "");
+ }
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ if (is_armature_target(data->tar)) {
+ uiDefButF(block, BUT, B_CONSTRAINT_TEST, "R", *xco, *yco-60, 20, 18, &data->dist, 0, 0, 0, 0, "Recalculate distance");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Distance:", *xco+18, *yco-60,139,18, &data->dist, 0.0, 100, 0.5, 0.5, "Radius of limiting sphere");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Head/Tail:", *xco+155, *yco-60,100,18, &con->headtail, 0.0, 1, 0.1, 0.1, "Target along length of bone: Head=0, Tail=1");
+ }
+ else {
+ uiDefButF(block, BUT, B_CONSTRAINT_TEST, "R", *xco, *yco-60, 20, 18, &data->dist, 0, 0, 0, 0, "Recalculate distance");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Distance:", *xco+18, *yco-60, 237, 18, &data->dist, 0.0, 100, 0.5, 0.5, "Radius of limiting sphere");
+ }
+
+ /* disabled soft-distance controls... currently it doesn't work yet. It was intended to be used for soft-ik (see xsi-blog for details) */
+#if 0
+ uiDefButBitS(block, TOG, LIMITDIST_USESOFT, B_CONSTRAINT_TEST, "Soft", *xco, *yco-82, 50, 18, &data->flag, 0, 24, 0, 0, "Enables soft-distance");
+ if (data->flag & LIMITDIST_USESOFT)
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Soft-Distance:", *xco+50, *yco-82, 187, 18, &data->soft, 0.0, 100, 0.5, 0.5, "Distance surrounding radius when transforms should get 'delayed'");
+#endif
+ uiBlockEndAlign(block);
+
+ uiDefButS(block, MENU, B_CONSTRAINT_TEST, "Limit Mode%t|Inside %x0|Outside %x1|Surface %x2", *xco+((width/2)-50), *yco-104, 100, 18, &data->mode, 0, 24, 0, 0, "Distances in relation to sphere of influence to allow");
+ }
+ break;
case CONSTRAINT_TYPE_RIGIDBODYJOINT:
{
bRigidBodyJointConstraint *data = con->data;
@@ -1748,6 +1796,7 @@ static uiBlock *add_constraintmenu(void *arg_unused)
uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCLIMIT, "Limit Location", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ROTLIMIT, "Limit Rotation", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
uiDefBut(block, BUTM, B_CONSTRAINT_ADD_SIZELIMIT, "Limit Scale", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefBut(block, BUTM, B_CONSTRAINT_ADD_DISTLIMIT, "Limit Distance", 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, "");
@@ -1980,6 +2029,14 @@ void do_constraintbuts(unsigned short event)
BIF_undo_push("Add constraint");
}
break;
+ case B_CONSTRAINT_ADD_DISTLIMIT:
+ {
+ con = add_new_constraint(CONSTRAINT_TYPE_DISTLIMIT);
+ add_constraint_to_active(ob, con);
+
+ BIF_undo_push("Add constraint");
+ }
+ break;
default:
break;
diff --git a/source/blender/src/editconstraint.c b/source/blender/src/editconstraint.c
index ac5129dd021..ba73767387e 100644
--- a/source/blender/src/editconstraint.c
+++ b/source/blender/src/editconstraint.c
@@ -364,21 +364,21 @@ void add_constraint (short only_IK)
else {
if (pchanact) {
if (pchansel)
- nr= pupmenu("Add Constraint to Active Bone%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
+ nr= pupmenu("Add Constraint to Active Bone%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
else if ((obsel) && (obsel->type==OB_CURVE))
- nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|Stretch To%x7|%l|Action%x16|Script%x18");
+ nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|Stretch To%x7|%l|Action%x16|Script%x18");
else if (obsel)
- nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
+ nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
else
- nr= pupmenu("Add Constraint to New Empty Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
+ nr= pupmenu("Add Constraint to New Empty Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
}
else {
if ((obsel) && (obsel->type==OB_CURVE))
- nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|%l|Action%x16|Script%x18");
+ nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|%l|Action%x16|Script%x18");
else if (obsel)
- nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Action%x16|Script%x18");
+ nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Action%x16|Script%x18");
else
- nr= pupmenu("Add Constraint to New Empty Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Action%x16|Script%x18");
+ nr= pupmenu("Add Constraint to New Empty Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Action%x16|Script%x18");
}
}
@@ -475,6 +475,7 @@ void add_constraint (short only_IK)
}
}
else if (nr==20) con = add_new_constraint(CONSTRAINT_TYPE_TRANSFORM);
+ else if (nr==21) con = add_new_constraint(CONSTRAINT_TYPE_DISTLIMIT);
if (con==NULL) return; /* paranoia */
diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c
index 6fe2e032eed..b3ea3e1931c 100644
--- a/source/blender/src/editipo.c
+++ b/source/blender/src/editipo.c
@@ -2515,7 +2515,7 @@ static int match_adr_constraint(ID * id, int blocktype, char *actname, int adrco
case CONSTRAINT_TYPE_LOCKTRACK:
if (searchtype==2) foundmatch=1;
break;
- case CONSTRAINT_TYPE_DISTANCELIMIT:
+ case CONSTRAINT_TYPE_DISTLIMIT:
if (searchtype==1) foundmatch=1;
break;
case CONSTRAINT_TYPE_MINMAX: