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
path: root/source
diff options
context:
space:
mode:
authorRoland Hess <me@harkyman.com>2010-03-16 15:55:56 +0300
committerRoland Hess <me@harkyman.com>2010-03-16 15:55:56 +0300
commitd617294c49912b1b0473bbbe58f62a3549641482 (patch)
treebbbb6645fb501d566047a43a0222137aacd50f93 /source
parent1cf95d2494ab82af61153abc3c45fa1a4fd3a4ed (diff)
New "Maintain Volume" constraint. When attached to a bone, you specify a "free" axis. Upon scaling, this free axis scales normally, but the constraint forces the other two axes to adjust themselves appropriately so that overall bone volume is maintained. So, setting "Y" as the free axis (the default) creates a bone that automatically squashes and stretches when scaling. Thanks to Aligorith, Fweeb, Cessen and others for the feedback.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/constraint.c59
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h14
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c32
3 files changed, 105 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 91bf4b8d8b2..08ac5e6acce 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -1859,6 +1859,64 @@ static bConstraintTypeInfo CTI_TRANSLIKE = {
translike_evaluate /* evaluate */
};
+/* ---------- Maintain Volume ---------- */
+
+static void samevolume_new_data (void *cdata)
+{
+ bSameVolumeConstraint *data= (bSameVolumeConstraint *)cdata;
+
+ data->flag = SAMEVOL_Y;
+ data->volume = 1.0f;
+}
+
+static void samevolume_evaluate (bConstraint *con, bConstraintOb *cob)
+{
+ bSameVolumeConstraint *data= con->data;
+
+ float obsize[3];
+ float volume=data->volume;
+
+ mat4_to_size(obsize, cob->matrix);
+
+ switch (data->flag) {
+ case SAMEVOL_X:
+ if (obsize[0]!=0) {
+ mul_v3_fl(cob->matrix[1], sqrt(volume/obsize[0])/obsize[0]);
+ mul_v3_fl(cob->matrix[2], sqrt(volume/obsize[0])/obsize[0]);
+ }
+ break;
+ case SAMEVOL_Y:
+ if (obsize[1]!=0) {
+ mul_v3_fl(cob->matrix[0], sqrt(volume/obsize[1])/obsize[1]);
+ mul_v3_fl(cob->matrix[2], sqrt(volume/obsize[1])/obsize[1]);
+ }
+ break;
+ case SAMEVOL_Z:
+ if (obsize[2]!=0) {
+ mul_v3_fl(cob->matrix[0], sqrt(volume/obsize[2])/obsize[2]);
+ mul_v3_fl(cob->matrix[1], sqrt(volume/obsize[2])/obsize[2]);
+ }
+ break;
+ }
+
+}
+
+static bConstraintTypeInfo CTI_SAMEVOL = {
+ CONSTRAINT_TYPE_SAMEVOL, /* type */
+ sizeof(bSameVolumeConstraint), /* size */
+ "Maintain Volume", /* name */
+ "bSameVolumeConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ NULL, /* id looper */
+ NULL, /* copy data */
+ samevolume_new_data, /* new data */
+ NULL, /* get constraint targets */
+ NULL, /* flush constraint targets */
+ NULL, /* get target matrix */
+ samevolume_evaluate /* evaluate */
+};
+
/* ----------- Python Constraint -------------- */
static void pycon_free (bConstraint *con)
@@ -3805,6 +3863,7 @@ static void constraints_init_typeinfo () {
constraintsTypeInfo[21]= &CTI_DAMPTRACK; /* Damped TrackTo Constraint */
constraintsTypeInfo[22]= &CTI_SPLINEIK; /* Spline IK Constraint */
constraintsTypeInfo[23]= &CTI_TRANSLIKE; /* Copy Transforms Constraint */
+ constraintsTypeInfo[24]= &CTI_SAMEVOL; /* Maintain Volume Constraint */
}
/* This function should be used for getting the appropriate type-info when only
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index 6e837588f0c..358cbb6e34c 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -208,6 +208,12 @@ typedef struct bSizeLikeConstraint {
char subtarget[32];
} bSizeLikeConstraint;
+/* Maintain Volume Constraint */
+typedef struct bSameVolumeConstraint {
+ int flag;
+ float volume;
+} bSameVolumeConstraint;
+
/* Copy Transform Constraint */
typedef struct bTransLikeConstraint {
Object *tar;
@@ -412,6 +418,7 @@ typedef enum eBConstraint_Types {
CONSTRAINT_TYPE_DAMPTRACK, /* New Tracking constraint that minimises twisting */
CONSTRAINT_TYPE_SPLINEIK, /* Spline-IK - Align 'n' bones to a curve */
CONSTRAINT_TYPE_TRANSLIKE, /* Copy transform matrix */
+ CONSTRAINT_TYPE_SAMEVOL, /* Maintain volume during scaling */
/* NOTE: no constraints are allowed to be added after this */
NUM_CONSTRAINT_TYPES
@@ -499,6 +506,13 @@ typedef enum eCopyScale_Flags {
SIZELIKE_OFFSET = (1<<3),
} eCopyScale_Flags;
+/* bSameVolumeConstraint.flag */
+typedef enum eSameVolume_Modes {
+ SAMEVOL_X = 0,
+ SAMEVOL_Y,
+ SAMEVOL_Z,
+} eSameVolume_Modes;
+
/* Locked-Axis Values (Locked Track) */
typedef enum eLockAxis_Modes {
LOCK_X = 0,
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index 65114804a3f..68a29fe9c83 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -50,6 +50,7 @@ EnumPropertyItem constraint_type_items[] ={
{CONSTRAINT_TYPE_LOCLIMIT, "LIMIT_LOCATION", ICON_CONSTRAINT_DATA, "Limit Location", ""},
{CONSTRAINT_TYPE_ROTLIMIT, "LIMIT_ROTATION", ICON_CONSTRAINT_DATA, "Limit Rotation", ""},
{CONSTRAINT_TYPE_SIZELIMIT, "LIMIT_SCALE", ICON_CONSTRAINT_DATA, "Limit Scale", ""},
+ {CONSTRAINT_TYPE_SAMEVOL, "MAINTAIN_VOLUME", ICON_CONSTRAINT_DATA, "Maintain Volume", ""},
{CONSTRAINT_TYPE_TRANSFORM, "TRANSFORM", ICON_CONSTRAINT_DATA, "Transformation", ""},
{0, "", 0, "Tracking", ""},
{CONSTRAINT_TYPE_CLAMPTO, "CLAMP_TO", ICON_CONSTRAINT_DATA, "Clamp To", ""},
@@ -124,6 +125,8 @@ static StructRNA *rna_ConstraintType_refine(struct PointerRNA *ptr)
return &RNA_CopyLocationConstraint;
case CONSTRAINT_TYPE_SIZELIKE:
return &RNA_CopyScaleConstraint;
+ case CONSTRAINT_TYPE_SAMEVOL:
+ return &RNA_MaintainVolumeConstraint;
case CONSTRAINT_TYPE_PYTHON:
return &RNA_PythonConstraint;
case CONSTRAINT_TYPE_ACTION:
@@ -813,6 +816,34 @@ static void rna_def_constraint_size_like(BlenderRNA *brna)
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
}
+static void rna_def_constraint_same_volume(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem volume_items[] = {
+ {SAMEVOL_X, "SAMEVOL_X", 0, "X", ""},
+ {SAMEVOL_Y, "SAMEVOL_Y", 0, "Y", ""},
+ {SAMEVOL_Z, "SAMEVOL_Z", 0, "Z", ""},
+ {0, NULL, 0, NULL, NULL}};
+
+ srna= RNA_def_struct(brna, "MaintainVolumeConstraint", "Constraint");
+ RNA_def_struct_ui_text(srna, "Maintain Volume Constraint", "Maintains a constant volume along a single scaling axis");
+ RNA_def_struct_sdna_from(srna, "bSameVolumeConstraint", "data");
+
+ prop= RNA_def_property(srna, "axis", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "flag");
+ RNA_def_property_enum_items(prop, volume_items);
+ RNA_def_property_ui_text(prop, "Free Axis", "The free scaling axis of the object");
+ RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop= RNA_def_property(srna, "volume", PROP_FLOAT, PROP_DISTANCE);
+ RNA_def_property_range(prop, 0.001, 100.f);
+ RNA_def_property_ui_text(prop, "Volume", "Volume of the bone at rest");
+ RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+
+}
+
static void rna_def_constraint_transform_like(BlenderRNA *brna)
{
StructRNA *srna;
@@ -1897,6 +1928,7 @@ void RNA_def_constraint(BlenderRNA *brna)
rna_def_constraint_locked_track(brna);
rna_def_constraint_action(brna);
rna_def_constraint_size_like(brna);
+ rna_def_constraint_same_volume(brna);
rna_def_constraint_locate_like(brna);
rna_def_constraint_rotate_like(brna);
rna_def_constraint_transform_like(brna);