Revision: 29024
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=29024
Author: aligorith
Date: 2010-05-27 12:50:06 +0200 (Thu, 27 May 2010)
Log Message:
-----------
== Pivot Constraint ==
This constraint allows an object or bone to have their rotations applied as if
their origin/pivot-point was located elsewhere. The most obvious uses include
foot-roll, see-saws, but could also include more complicated rolling-box
examples.
== Usage Examples ==
=== Foot Roll ===
1. Add 'Pivot' Constraint to the bone without any target.
2. Set the 'Y' value of the offset to the length of the bone. Usually this
should be negative (if you rig with feet facing 'forwards' along -Y axis). This
gives you a pivot point relative to the bone's (preconstraint) location, which
should be at the tip of the bone here. Disabling the 'Use Relative Offset'
would make this offset be relative to 0,0,0 instead of to the owner/bone-head.
3. Ensure that the 'Pivot When' setting is set to '-X Rot', (default) which
means that the pivot will only used when the rotation on the X-Axis is negative
to get tip-toe 'roll'.
=== See Saw ===
1. Add a 'Pivot' constraint too see-saw plank object, this time with a target
that you wish to have as the pivot-point. It's possible to do this without too
(as before), but is less intuitive.
2. Optionally, if you want the plank slightly raised, set the z-offset value,
which should make the pivot-point used to be relative to the target with the
z-offset applied.
3. Ensure that 'Pivot When' is set to 'Always', which means that the pivot will
always be used, irrespective of the rotation.
== Notes ==
* The 'Pivot When' setting has been integrated in the constraint, since this is
something that will often be required for these setups. Having to set up
additional drivers to drive the constraint to do this kindof beats the purpose
of providing this.
* The 'Offset' functionality is probably not presented as clearly as it could
be. We may need to go over this again.
* For foot-roll - if any scaling of the foot is required, simply set up a
driver on the y-offset to make this dynamically respond to the "scale" RNA
property of the bones (don't use the "Transform Channel" vartype since that
won't work correct here). However, this shouldn't be common enough to warrant
special treatment.
Modified Paths:
--------------
trunk/blender/release/scripts/ui/properties_object_constraint.py
trunk/blender/source/blender/blenkernel/intern/constraint.c
trunk/blender/source/blender/editors/object/object_constraint.c
trunk/blender/source/blender/makesdna/DNA_constraint_types.h
trunk/blender/source/blender/makesrna/RNA_access.h
trunk/blender/source/blender/makesrna/intern/rna_constraint.c
Modified: trunk/blender/release/scripts/ui/properties_object_constraint.py
===================================================================
--- trunk/blender/release/scripts/ui/properties_object_constraint.py
2010-05-27 09:23:26 UTC (rev 29023)
+++ trunk/blender/release/scripts/ui/properties_object_constraint.py
2010-05-27 10:50:06 UTC (rev 29024)
@@ -76,7 +76,7 @@
else:
layout.prop_object(con, "subtarget", con.target.data,
"bones", text="")
- if con.type in ('COPY_LOCATION', 'STRETCH_TO', 'TRACK_TO'):
+ if con.type in ('COPY_LOCATION', 'STRETCH_TO', 'TRACK_TO',
'PIVOT'):
row = layout.row()
row.label(text="Head/Tail:")
row.prop(con, "head_tail", text="")
@@ -730,7 +730,23 @@
col.prop(con, "xz_scaling_mode", text="")
col.prop(con, "use_curve_radius")
+ def PIVOT(self, context, layout, con, wide_ui):
+ self.target_template(layout, con, wide_ui)
+ if con.target:
+ col = layout.column()
+ col.prop(con, "offset", text="Pivot Offset")
+ else:
+ col = layout.column()
+ col.prop(con, "use_relative_position")
+ if con.use_relative_position:
+ col.prop(con, "offset", text="Relative Pivot Point")
+ else:
+ col.prop(con, "offset", text="Absolute Pivot Point")
+
+ col = layout.column()
+ col.prop(con, "enabled_rotation_range", text="Pivot When")
+
class OBJECT_PT_constraints(ConstraintButtonsPanel):
bl_label = "Object Constraints"
bl_context = "constraint"
Modified: trunk/blender/source/blender/blenkernel/intern/constraint.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/constraint.c 2010-05-27
09:23:26 UTC (rev 29023)
+++ trunk/blender/source/blender/blenkernel/intern/constraint.c 2010-05-27
10:50:06 UTC (rev 29024)
@@ -3831,6 +3831,118 @@
NULL /* evaluate - solved as separate loop */
};
+/* ----------- Pivot ------------- */
+
+static void pivotcon_id_looper (bConstraint *con, ConstraintIDFunc func, void
*userdata)
+{
+ bPivotConstraint *data= con->data;
+
+ /* target only */
+ func(con, (ID**)&data->tar, userdata);
+}
+
+static int pivotcon_get_tars (bConstraint *con, ListBase *list)
+{
+ if (con && list) {
+ bPivotConstraint *data= con->data;
+ bConstraintTarget *ct;
+
+ /* standard target-getting macro for single-target constraints
*/
+ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static void pivotcon_flush_tars (bConstraint *con, ListBase *list, short
nocopy)
+{
+ if (con && list) {
+ bPivotConstraint *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 pivotcon_evaluate (bConstraint *con, bConstraintOb *cob, ListBase
*targets)
+{
+ bPivotConstraint *data= con->data;
+ bConstraintTarget *ct= targets->first;
+
+ float pivot[3], vec[3];
+ float rotMat[3][3];
+
+ /* firstly, check if pivoting should take place based on the current
rotation */
+ if (data->rotAxis != PIVOTCON_AXIS_NONE) {
+ float rot[3];
+
+ /* extract euler-rotation of target */
+ mat4_to_eulO(rot, cob->rotOrder, cob->matrix);
+
+ /* check which range might be violated */
+ if (data->rotAxis < PIVOTCON_AXIS_X) {
+ /* negative rotations (data->rotAxis = 0 -> 2) */
+ if (rot[data->rotAxis] > 0.0f)
+ return;
+ }
+ else {
+ /* positive rotations (data->rotAxis = 3 -> 5 */
+ if (rot[data->rotAxis - PIVOTCON_AXIS_X] < 0.0f)
+ return;
+ }
+ }
+
+ /* find the pivot-point to use */
+ if (VALID_CONS_TARGET(ct)) {
+ /* apply offset to target location */
+ add_v3_v3v3(pivot, ct->matrix[3], data->offset);
+ }
+ else {
+ /* no targets to worry about... */
+ if ((data->flag & PIVOTCON_FLAG_OFFSET_ABS) == 0) {
+ /* offset is relative to owner */
+ add_v3_v3v3(pivot, cob->matrix[3], data->offset);
+ }
+ else {
+ /* directly use the 'offset' specified as an absolute
position instead */
+ VECCOPY(pivot, data->offset);
+ }
+ }
+
+ /* get rotation matrix representing the rotation of the owner */
+ // TODO: perhaps we might want to include scaling based on the pivot
too?
+ copy_m3_m4(rotMat, cob->matrix);
+ normalize_m3(rotMat);
+
+ /* perform the pivoting... */
+ /* 1. take the vector from owner to the pivot */
+ sub_v3_v3v3(vec, pivot, cob->matrix[3]);
+ /* 2. rotate this vector by the rotation of the object... */
+ mul_m3_v3(rotMat, vec);
+ /* 3. make the rotation in terms of the pivot now */
+ add_v3_v3v3(cob->matrix[3], pivot, vec);
+}
+
+
+static bConstraintTypeInfo CTI_PIVOT = {
+ CONSTRAINT_TYPE_PIVOT, /* type */
+ sizeof(bPivotConstraint), /* size */
+ "Pivot", /* name */
+ "bPivotConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ pivotcon_id_looper, /* id looper */
+ NULL, /* copy data */
+ NULL, /* new data */ // XXX: might be needed to get 'normal' pivot
behaviour...
+ pivotcon_get_tars, /* get constraint targets */
+ pivotcon_flush_tars, /* flush constraint targets */
+ default_get_tarmat, /* get target matrix */
+ pivotcon_evaluate /* evaluate */
+};
+
/* ************************* Constraints Type-Info ***************************
*/
/* All of the constraints api functions use bConstraintTypeInfo structs to
carry out
* and operations that involve constraint specific code.
@@ -3867,6 +3979,7 @@
constraintsTypeInfo[22]= &CTI_SPLINEIK; /* Spline IK
Constraint */
constraintsTypeInfo[23]= &CTI_TRANSLIKE; /* Copy
Transforms Constraint */
constraintsTypeInfo[24]= &CTI_SAMEVOL; /* Maintain
Volume Constraint */
+ constraintsTypeInfo[25]= &CTI_PIVOT; /* Pivot
Constraint */
}
/* This function should be used for getting the appropriate type-info when only
Modified: trunk/blender/source/blender/editors/object/object_constraint.c
===================================================================
--- trunk/blender/source/blender/editors/object/object_constraint.c
2010-05-27 09:23:26 UTC (rev 29023)
+++ trunk/blender/source/blender/editors/object/object_constraint.c
2010-05-27 10:50:06 UTC (rev 29024)
@@ -322,6 +322,23 @@
/* targets have already been checked for this */
continue;
}
+ else if (curcon->type == CONSTRAINT_TYPE_PIVOT) {
+ bPivotConstraint *data = curcon->data;
+
+ /* target doesn't have to exist, but if it is
non-null, it must exist! */
+ if (data->tar && exist_object(data->tar)==0) {
+ data->tar = NULL;
+ curcon->flag |= CONSTRAINT_DISABLE;
+ }
+ else if (data->tar == owner) {
+ if
(!get_named_bone(get_armature(owner), data->subtarget)) {
+ curcon->flag |=
CONSTRAINT_DISABLE;
+ }
+ }
+
+ /* targets have already been checked for this */
+ continue;
+ }
else if (curcon->type == CONSTRAINT_TYPE_ACTION) {
bActionConstraint *data = curcon->data;
Modified: trunk/blender/source/blender/makesdna/DNA_constraint_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_constraint_types.h
2010-05-27 09:23:26 UTC (rev 29023)
+++ trunk/blender/source/blender/makesdna/DNA_constraint_types.h
2010-05-27 10:50:06 UTC (rev 29024)
@@ -174,6 +174,7 @@
/* Single-target subobject constraints --------------------- */
+
/* Track To Constraint */
typedef struct bTrackToConstraint {
Object *tar;
@@ -336,6 +337,24 @@
float to_max[3];
} bTransformConstraint;
+/* Pivot Constraint */
+typedef struct bPivotConstraint {
+ /* Pivot Point:
+ * Either target object + offset, or just offset is used
+ */
+ Object *tar; /* target object (optional) */
+ char subtarget[32]; /* subtarget name (optional) */
+ float offset[3]; /* offset from the target to
use, regardless of whether it exists */
+
+ /* Rotation-driven activation:
+ * This option provides easier one-stop setups for footrolls
+ */
+ short rotAxis; /* rotation axes to consider
for this (ePivotConstraint_Axis) */
+
+ /* General flags */
+ short flag; /* ePivotConstraint_Flag */
+} bPivotConstraint;
+
/* transform limiting constraints - zero target ----------------------------
*/
/* Limit Location Constraint */
typedef struct bLocLimitConstraint {
@@ -419,6 +438,7 @@
CONSTRAINT_TYPE_SPLINEIK, /* Spline-IK - Align
'n' bones to a curve */
CONSTRAINT_TYPE_TRANSLIKE, /* Copy transform
matrix */
CONSTRAINT_TYPE_SAMEVOL, /* Maintain volume
during scaling */
+ CONSTRAINT_TYPE_PIVOT, /* Pivot Constraint */
/* NOTE: no constraints are allowed to be added after this */
NUM_CONSTRAINT_TYPES
@@ -469,11 +489,6 @@
/* -------------------------------------- */
-/**
- * The flags for ROTLIKE, LOCLIKE and SIZELIKE should be kept identical
- * (that is, same effect, different name). It simplifies the Python API access
a lot.
- */
-
/* bRotateLikeConstraint.flag */
typedef enum eCopyRotation_Flags {
ROTLIKE_X = (1<<0),
@@ -688,6 +703,35 @@
CHILDOF_SIZEZ = (1<<8),
} eChildOf_Flags;
+/* Pivot Constraint */
+ /* Restrictions for Pivot Constraint axis to consider for enabling
constraint */
+typedef enum ePivotConstraint_Axis {
+ /* do not consider this activity-clamping */
+ PIVOTCON_AXIS_NONE = -1,
+
+ /* consider -ve x-axis rotations */
+ PIVOTCON_AXIS_X_NEG,
+ /* consider -ve y-axis rotations */
+ PIVOTCON_AXIS_Y_NEG,
+ /* consider -ve z-axis rotations */
+ PIVOTCON_AXIS_Z_NEG,
+
+ /* consider +ve x-axis rotations */
+ PIVOTCON_AXIS_X,
+ /* consider +ve y-axis rotations */
+ PIVOTCON_AXIS_Y,
+ /* consider +ve z-axis rotations */
+ PIVOTCON_AXIS_Z,
+} ePivotConstraint_Axis;
+
+ /* settings for Pivot Constraint in general */
+typedef enum ePivotConstraint_Flag {
+ /* offset is to be interpreted as being a fixed-point in space */
+ PIVOTCON_FLAG_OFFSET_ABS = (1<<0),
+ /* rotation-based activation uses negative rotation to drive result */
+ PIVOTCON_FLAG_ROTACT_NEG = (1<<1),
+} ePivotConstraint_Flag;
+
/* Rigid-Body Constraint */
#define CONSTRAINT_DRAW_PIVOT 0x40
#define CONSTRAINT_DISABLE_LINKED_COLLISION 0x80
Modified: trunk/blender/source/blender/makesrna/RNA_access.h
===================================================================
@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs