Compare commits
2 Commits
xr-control
...
temp-angav
Author | SHA1 | Date | |
---|---|---|---|
db24fc4f27 | |||
71b595fc0e |
@@ -496,6 +496,8 @@ class ConstraintButtonsPanel(Panel):
|
||||
|
||||
self.target_template(layout, con)
|
||||
|
||||
layout.prop(con, "invert")
|
||||
layout.prop(con, "split_mode", text="Components")
|
||||
layout.prop(con, "mix_mode", text="Mix")
|
||||
|
||||
self.space_template(layout, con)
|
||||
|
@@ -198,6 +198,7 @@ void BKE_constraints_clear_evalob(struct bConstraintOb *cob);
|
||||
void BKE_constraint_mat_convertspace(struct Object *ob,
|
||||
struct bPoseChannel *pchan,
|
||||
float mat[4][4],
|
||||
bConstraintOb *cob,
|
||||
short from,
|
||||
short to,
|
||||
const bool keep_scale);
|
||||
|
@@ -255,8 +255,13 @@ void BKE_constraints_clear_evalob(bConstraintOb *cob)
|
||||
* of a matrix from one space to another for constraint evaluation.
|
||||
* For now, this is only implemented for Objects and PoseChannels.
|
||||
*/
|
||||
void BKE_constraint_mat_convertspace(
|
||||
Object *ob, bPoseChannel *pchan, float mat[4][4], short from, short to, const bool keep_scale)
|
||||
void BKE_constraint_mat_convertspace(Object *ob,
|
||||
bPoseChannel *pchan,
|
||||
float mat[4][4],
|
||||
bConstraintOb *cob,
|
||||
short from,
|
||||
short to,
|
||||
const bool keep_scale)
|
||||
{
|
||||
float diff_mat[4][4];
|
||||
float imat[4][4];
|
||||
@@ -281,9 +286,10 @@ void BKE_constraint_mat_convertspace(
|
||||
mul_m4_m4m4(mat, imat, mat);
|
||||
|
||||
/* use pose-space as stepping stone for other spaces... */
|
||||
if (ELEM(to, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_PARLOCAL)) {
|
||||
if (to != CONSTRAINT_SPACE_POSE) {
|
||||
/* call self with slightly different values */
|
||||
BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
|
||||
BKE_constraint_mat_convertspace(
|
||||
ob, pchan, mat, cob, CONSTRAINT_SPACE_POSE, to, keep_scale);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -294,9 +300,25 @@ void BKE_constraint_mat_convertspace(
|
||||
mul_m4_m4m4(mat, ob->obmat, mat);
|
||||
}
|
||||
/* pose to local */
|
||||
else if (to == CONSTRAINT_SPACE_LOCAL) {
|
||||
else if (ELEM(to,
|
||||
CONSTRAINT_SPACE_LOCAL,
|
||||
CONSTRAINT_SPACE_ABSLOCAL,
|
||||
CONSTRAINT_SPACE_OWNLOCAL)) {
|
||||
if (pchan->bone) {
|
||||
BKE_armature_mat_pose_to_bone(pchan, mat, mat);
|
||||
|
||||
if (to != CONSTRAINT_SPACE_LOCAL) {
|
||||
copy_m4_m4(diff_mat, pchan->bone->arm_mat);
|
||||
|
||||
if (to == CONSTRAINT_SPACE_OWNLOCAL && cob && cob->pchan && cob->pchan->bone) {
|
||||
invert_m4_m4(imat, cob->pchan->bone->arm_mat);
|
||||
mul_m4_m4m4(diff_mat, imat, diff_mat);
|
||||
}
|
||||
|
||||
zero_v3(diff_mat[3]);
|
||||
invert_m4_m4(imat, diff_mat);
|
||||
mul_m4_series(mat, diff_mat, mat, imat);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* pose to local with parent */
|
||||
@@ -309,17 +331,32 @@ void BKE_constraint_mat_convertspace(
|
||||
break;
|
||||
}
|
||||
case CONSTRAINT_SPACE_LOCAL: /* ------------ FROM LOCALSPACE --------- */
|
||||
{
|
||||
case CONSTRAINT_SPACE_ABSLOCAL:
|
||||
case CONSTRAINT_SPACE_OWNLOCAL: {
|
||||
/* local to pose - do inverse procedure that was done for pose to local */
|
||||
if (pchan->bone) {
|
||||
if (from != CONSTRAINT_SPACE_LOCAL) {
|
||||
copy_m4_m4(diff_mat, pchan->bone->arm_mat);
|
||||
|
||||
if (from == CONSTRAINT_SPACE_OWNLOCAL && cob && cob->pchan && cob->pchan->bone) {
|
||||
invert_m4_m4(imat, cob->pchan->bone->arm_mat);
|
||||
mul_m4_m4m4(diff_mat, imat, diff_mat);
|
||||
}
|
||||
|
||||
zero_v3(diff_mat[3]);
|
||||
invert_m4_m4(imat, diff_mat);
|
||||
mul_m4_series(mat, imat, mat, diff_mat);
|
||||
}
|
||||
|
||||
/* we need the posespace_matrix = local_matrix + (parent_posespace_matrix + restpos) */
|
||||
BKE_armature_mat_bone_to_pose(pchan, mat, mat);
|
||||
}
|
||||
|
||||
/* use pose-space as stepping stone for other spaces */
|
||||
if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_PARLOCAL)) {
|
||||
if (to != CONSTRAINT_SPACE_POSE) {
|
||||
/* call self with slightly different values */
|
||||
BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
|
||||
BKE_constraint_mat_convertspace(
|
||||
ob, pchan, mat, cob, CONSTRAINT_SPACE_POSE, to, keep_scale);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -331,9 +368,10 @@ void BKE_constraint_mat_convertspace(
|
||||
}
|
||||
|
||||
/* use pose-space as stepping stone for other spaces */
|
||||
if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL)) {
|
||||
if (to != CONSTRAINT_SPACE_POSE) {
|
||||
/* call self with slightly different values */
|
||||
BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
|
||||
BKE_constraint_mat_convertspace(
|
||||
ob, pchan, mat, cob, CONSTRAINT_SPACE_POSE, to, keep_scale);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -568,6 +606,7 @@ static void contarget_get_lattice_mat(Object *ob, const char *substring, float m
|
||||
static void constraint_target_to_mat4(Object *ob,
|
||||
const char *substring,
|
||||
float mat[4][4],
|
||||
bConstraintOb *cob,
|
||||
short from,
|
||||
short to,
|
||||
short flag,
|
||||
@@ -576,7 +615,7 @@ static void constraint_target_to_mat4(Object *ob,
|
||||
/* Case OBJECT */
|
||||
if (substring[0] == '\0') {
|
||||
copy_m4_m4(mat, ob->obmat);
|
||||
BKE_constraint_mat_convertspace(ob, NULL, mat, from, to, false);
|
||||
BKE_constraint_mat_convertspace(ob, NULL, mat, cob, from, to, false);
|
||||
}
|
||||
/* Case VERTEXGROUP */
|
||||
/* Current method just takes the average location of all the points in the
|
||||
@@ -589,11 +628,11 @@ static void constraint_target_to_mat4(Object *ob,
|
||||
*/
|
||||
else if (ob->type == OB_MESH) {
|
||||
contarget_get_mesh_mat(ob, substring, mat);
|
||||
BKE_constraint_mat_convertspace(ob, NULL, mat, from, to, false);
|
||||
BKE_constraint_mat_convertspace(ob, NULL, mat, cob, from, to, false);
|
||||
}
|
||||
else if (ob->type == OB_LATTICE) {
|
||||
contarget_get_lattice_mat(ob, substring, mat);
|
||||
BKE_constraint_mat_convertspace(ob, NULL, mat, from, to, false);
|
||||
BKE_constraint_mat_convertspace(ob, NULL, mat, cob, from, to, false);
|
||||
}
|
||||
/* Case BONE */
|
||||
else {
|
||||
@@ -656,7 +695,7 @@ static void constraint_target_to_mat4(Object *ob,
|
||||
}
|
||||
|
||||
/* convert matrix space as required */
|
||||
BKE_constraint_mat_convertspace(ob, pchan, mat, from, to, false);
|
||||
BKE_constraint_mat_convertspace(ob, pchan, mat, cob, from, to, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -699,7 +738,7 @@ static bConstraintTypeInfo CTI_CONSTRNAME = {
|
||||
*/
|
||||
static void default_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
|
||||
bConstraint *con,
|
||||
bConstraintOb *UNUSED(cob),
|
||||
bConstraintOb *cob,
|
||||
bConstraintTarget *ct,
|
||||
float UNUSED(ctime))
|
||||
{
|
||||
@@ -707,6 +746,7 @@ static void default_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
|
||||
constraint_target_to_mat4(ct->tar,
|
||||
ct->subtarget,
|
||||
ct->matrix,
|
||||
cob,
|
||||
CONSTRAINT_SPACE_WORLD,
|
||||
ct->space,
|
||||
con->flag,
|
||||
@@ -721,7 +761,7 @@ static void default_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
|
||||
*/
|
||||
static void default_get_tarmat_full_bbone(struct Depsgraph *UNUSED(depsgraph),
|
||||
bConstraint *con,
|
||||
bConstraintOb *UNUSED(cob),
|
||||
bConstraintOb *cob,
|
||||
bConstraintTarget *ct,
|
||||
float UNUSED(ctime))
|
||||
{
|
||||
@@ -729,6 +769,7 @@ static void default_get_tarmat_full_bbone(struct Depsgraph *UNUSED(depsgraph),
|
||||
constraint_target_to_mat4(ct->tar,
|
||||
ct->subtarget,
|
||||
ct->matrix,
|
||||
cob,
|
||||
CONSTRAINT_SPACE_WORLD,
|
||||
ct->space,
|
||||
con->flag | CONSTRAINT_BBONE_SHAPE_FULL,
|
||||
@@ -1257,6 +1298,7 @@ static void kinematic_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
|
||||
constraint_target_to_mat4(ct->tar,
|
||||
ct->subtarget,
|
||||
ct->matrix,
|
||||
cob,
|
||||
CONSTRAINT_SPACE_WORLD,
|
||||
ct->space,
|
||||
con->flag,
|
||||
@@ -2106,21 +2148,108 @@ static void translike_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
|
||||
bConstraintTarget *ct = targets->first;
|
||||
|
||||
if (VALID_CONS_TARGET(ct)) {
|
||||
switch (data->mix_mode) {
|
||||
case TRANSLIKE_MIX_REPLACE:
|
||||
copy_m4_m4(cob->matrix, ct->matrix);
|
||||
break;
|
||||
float mat[4][4], scale[3];
|
||||
copy_m4_m4(mat, ct->matrix);
|
||||
|
||||
case TRANSLIKE_MIX_BEFORE:
|
||||
mul_m4_m4m4_aligned_scale(cob->matrix, ct->matrix, cob->matrix);
|
||||
break;
|
||||
switch (data->split_mode) {
|
||||
case TRANSLIKE_SPLIT_NONE: {
|
||||
if (data->flag & TRANSLIKE_INVERT) {
|
||||
invert_m4(mat);
|
||||
}
|
||||
|
||||
case TRANSLIKE_MIX_AFTER:
|
||||
mul_m4_m4m4_aligned_scale(cob->matrix, cob->matrix, ct->matrix);
|
||||
switch (data->mix_mode) {
|
||||
case TRANSLIKE_MIX_REPLACE:
|
||||
copy_m4_m4(cob->matrix, mat);
|
||||
break;
|
||||
|
||||
case TRANSLIKE_MIX_BEFORE:
|
||||
mul_m4_m4m4(cob->matrix, mat, cob->matrix);
|
||||
break;
|
||||
|
||||
case TRANSLIKE_MIX_AFTER:
|
||||
mul_m4_m4m4(cob->matrix, cob->matrix, mat);
|
||||
break;
|
||||
|
||||
default:
|
||||
BLI_assert(!"Unknown Copy Transforms mix mode");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TRANSLIKE_SPLIT_SCALE: {
|
||||
orthogonalize_m4_stable(mat, 1, false);
|
||||
|
||||
if (data->flag & TRANSLIKE_INVERT) {
|
||||
normalize_m4_ex(mat, scale);
|
||||
invert_m4(mat);
|
||||
invert_v3(scale);
|
||||
rescale_m4(mat, scale);
|
||||
}
|
||||
|
||||
switch (data->mix_mode) {
|
||||
case TRANSLIKE_MIX_REPLACE:
|
||||
copy_m4_m4(cob->matrix, mat);
|
||||
break;
|
||||
|
||||
case TRANSLIKE_MIX_BEFORE:
|
||||
mul_m4_m4m4_aligned_scale(cob->matrix, mat, cob->matrix);
|
||||
break;
|
||||
|
||||
case TRANSLIKE_MIX_AFTER:
|
||||
mul_m4_m4m4_aligned_scale(cob->matrix, cob->matrix, mat);
|
||||
break;
|
||||
|
||||
default:
|
||||
BLI_assert(!"Unknown Copy Transforms mix mode");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TRANSLIKE_SPLIT_ALL: {
|
||||
float loc_a[3], rot_a[3][3], size_a[3];
|
||||
float loc_b[3], rot_b[3][3], size_b[3];
|
||||
float loc_r[3], rot_r[3][3], size_r[3];
|
||||
|
||||
orthogonalize_m4_stable(mat, 1, false);
|
||||
|
||||
mat4_to_loc_rot_size(loc_a, rot_a, size_a, cob->matrix);
|
||||
mat4_to_loc_rot_size(loc_b, rot_b, size_b, mat);
|
||||
|
||||
if (data->flag & TRANSLIKE_INVERT) {
|
||||
negate_v3(loc_b);
|
||||
invert_m3(rot_b);
|
||||
invert_v3(size_b);
|
||||
}
|
||||
|
||||
switch (data->mix_mode) {
|
||||
case TRANSLIKE_MIX_REPLACE:
|
||||
copy_v3_v3(loc_r, loc_b);
|
||||
copy_m3_m3(rot_r, rot_b);
|
||||
copy_v3_v3(size_r, size_b);
|
||||
break;
|
||||
|
||||
case TRANSLIKE_MIX_BEFORE:
|
||||
add_v3_v3v3(loc_r, loc_a, loc_b);
|
||||
mul_m3_m3m3_uniq(rot_r, rot_b, rot_a);
|
||||
mul_v3_v3v3(size_r, size_a, size_b);
|
||||
break;
|
||||
|
||||
case TRANSLIKE_MIX_AFTER:
|
||||
add_v3_v3v3(loc_r, loc_a, loc_b);
|
||||
mul_m3_m3m3_uniq(rot_r, rot_a, rot_b);
|
||||
mul_v3_v3v3(size_r, size_a, size_b);
|
||||
break;
|
||||
|
||||
default:
|
||||
BLI_assert(!"Unknown Copy Transforms mix mode");
|
||||
}
|
||||
|
||||
loc_rot_size_to_mat4(cob->matrix, loc_r, rot_r, size_r);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
BLI_assert(!"Unknown Copy Transforms mix mode");
|
||||
BLI_assert(!"Unknown Copy Transforms split mode");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2271,7 +2400,7 @@ static void pycon_id_looper(bConstraint *con, ConstraintIDFunc func, void *userd
|
||||
/* Whether this approach is maintained remains to be seen (aligorith) */
|
||||
static void pycon_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
|
||||
bConstraint *con,
|
||||
bConstraintOb *UNUSED(cob),
|
||||
bConstraintOb *cob,
|
||||
bConstraintTarget *ct,
|
||||
float UNUSED(ctime))
|
||||
{
|
||||
@@ -2291,6 +2420,7 @@ static void pycon_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
|
||||
constraint_target_to_mat4(ct->tar,
|
||||
ct->subtarget,
|
||||
ct->matrix,
|
||||
cob,
|
||||
CONSTRAINT_SPACE_WORLD,
|
||||
ct->space,
|
||||
con->flag,
|
||||
@@ -2651,6 +2781,7 @@ static void actcon_get_tarmat(struct Depsgraph *depsgraph,
|
||||
constraint_target_to_mat4(ct->tar,
|
||||
ct->subtarget,
|
||||
tempmat,
|
||||
cob,
|
||||
CONSTRAINT_SPACE_WORLD,
|
||||
ct->space,
|
||||
con->flag,
|
||||
@@ -4112,7 +4243,7 @@ static void shrinkwrap_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
|
||||
* See T42447. */
|
||||
unit_m4(mat);
|
||||
BKE_constraint_mat_convertspace(
|
||||
cob->ob, cob->pchan, mat, CONSTRAINT_SPACE_LOCAL, scon->projAxisSpace, true);
|
||||
cob->ob, cob->pchan, mat, cob, CONSTRAINT_SPACE_LOCAL, scon->projAxisSpace, true);
|
||||
invert_m4(mat);
|
||||
mul_mat3_m4_v3(mat, no);
|
||||
|
||||
@@ -6044,7 +6175,7 @@ void BKE_constraints_solve(struct Depsgraph *depsgraph,
|
||||
|
||||
/* move owner matrix into right space */
|
||||
BKE_constraint_mat_convertspace(
|
||||
cob->ob, cob->pchan, cob->matrix, CONSTRAINT_SPACE_WORLD, con->ownspace, false);
|
||||
cob->ob, cob->pchan, cob->matrix, cob, CONSTRAINT_SPACE_WORLD, con->ownspace, false);
|
||||
|
||||
/* prepare targets for constraint solving */
|
||||
BKE_constraint_targets_for_solving_get(depsgraph, con, cob, &targets, ctime);
|
||||
@@ -6063,7 +6194,7 @@ void BKE_constraints_solve(struct Depsgraph *depsgraph,
|
||||
/* move owner back into world-space for next constraint/other business */
|
||||
if ((con->flag & CONSTRAINT_SPACEONCE) == 0) {
|
||||
BKE_constraint_mat_convertspace(
|
||||
cob->ob, cob->pchan, cob->matrix, con->ownspace, CONSTRAINT_SPACE_WORLD, false);
|
||||
cob->ob, cob->pchan, cob->matrix, cob, con->ownspace, CONSTRAINT_SPACE_WORLD, false);
|
||||
}
|
||||
|
||||
/* Interpolate the enforcement, to blend result of constraint into final owner transform
|
||||
|
@@ -411,7 +411,7 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
|
||||
/* Extract transform just like how the constraints do it! */
|
||||
copy_m4_m4(mat, pchan->pose_mat);
|
||||
BKE_constraint_mat_convertspace(
|
||||
ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL, false);
|
||||
ob, pchan, mat, NULL, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL, false);
|
||||
|
||||
/* ... and from that, we get our transform. */
|
||||
copy_v3_v3(tmp_loc, mat[3]);
|
||||
@@ -437,7 +437,7 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
|
||||
/* Extract transform just like how the constraints do it! */
|
||||
copy_m4_m4(mat, ob->obmat);
|
||||
BKE_constraint_mat_convertspace(
|
||||
ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, false);
|
||||
ob, NULL, mat, NULL, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, false);
|
||||
|
||||
/* ... and from that, we get our transform. */
|
||||
copy_v3_v3(tmp_loc, mat[3]);
|
||||
@@ -514,7 +514,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
|
||||
/* Just like how the constraints do it! */
|
||||
copy_m4_m4(mat, pchan->pose_mat);
|
||||
BKE_constraint_mat_convertspace(
|
||||
ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL, false);
|
||||
ob, pchan, mat, NULL, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL, false);
|
||||
}
|
||||
else {
|
||||
/* Specially calculate local matrix, since chan_mat is not valid
|
||||
@@ -541,7 +541,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
|
||||
/* Just like how the constraints do it! */
|
||||
copy_m4_m4(mat, ob->obmat);
|
||||
BKE_constraint_mat_convertspace(
|
||||
ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, false);
|
||||
ob, NULL, mat, NULL, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, false);
|
||||
}
|
||||
else {
|
||||
/* Transforms to matrix. */
|
||||
|
@@ -326,6 +326,17 @@ static void do_versions_291_fcurve_handles_limit(FCurve *fcu)
|
||||
}
|
||||
}
|
||||
|
||||
static void do_version_constraints_copy_transforms_split_mode(ListBase *lb)
|
||||
{
|
||||
LISTBASE_FOREACH (bConstraint *, con, lb) {
|
||||
if (con->type == CONSTRAINT_TYPE_TRANSLIKE) {
|
||||
bTransLikeConstraint *data = (bTransLikeConstraint *)con->data;
|
||||
data->split_mode = (data->mix_mode == TRANSLIKE_MIX_REPLACE) ? TRANSLIKE_SPLIT_NONE :
|
||||
TRANSLIKE_SPLIT_SCALE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
||||
{
|
||||
UNUSED_VARS(fd);
|
||||
@@ -759,5 +770,17 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
||||
mesh->symmetry = mesh->editflag & (ME_SYMMETRY_X | ME_SYMMETRY_Y | ME_SYMMETRY_Z);
|
||||
}
|
||||
}
|
||||
|
||||
/* Split mode in Copy Transforms constraint. */
|
||||
if (!DNA_struct_elem_find(fd->filesdna, "bTransLikeConstraint", "char", "split_mode")) {
|
||||
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
|
||||
do_version_constraints_copy_transforms_split_mode(&ob->constraints);
|
||||
if (ob->pose) {
|
||||
LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
|
||||
do_version_constraints_copy_transforms_split_mode(&pchan->constraints);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -442,20 +442,19 @@ static void updateDuplicateSubtarget(EditBone *dup_bone,
|
||||
}
|
||||
}
|
||||
|
||||
static void updateDuplicateActionConstraintSettings(EditBone *dup_bone,
|
||||
EditBone *orig_bone,
|
||||
Object *ob,
|
||||
bConstraint *curcon)
|
||||
static void updateDuplicateActionConstraintSettings(
|
||||
EditBone *dup_bone, EditBone *orig_bone, Object *ob, bPoseChannel *pchan, bConstraint *curcon)
|
||||
{
|
||||
bActionConstraint *act_con = (bActionConstraint *)curcon->data;
|
||||
bAction *act = (bAction *)act_con->act;
|
||||
bConstraintOb cob = {.depsgraph = NULL, .scene = NULL, .ob = ob, .pchan = pchan};
|
||||
|
||||
float mat[4][4];
|
||||
|
||||
unit_m4(mat);
|
||||
bPoseChannel *target_pchan = BKE_pose_channel_find_name(ob->pose, act_con->subtarget);
|
||||
BKE_constraint_mat_convertspace(
|
||||
ob, target_pchan, mat, curcon->tarspace, CONSTRAINT_SPACE_LOCAL, false);
|
||||
ob, target_pchan, mat, &cob, curcon->tarspace, CONSTRAINT_SPACE_LOCAL, false);
|
||||
|
||||
float max_axis_val = 0;
|
||||
int max_axis = 0;
|
||||
@@ -592,6 +591,8 @@ static void updateDuplicateLocRotConstraintSettings(Object *ob,
|
||||
bRotLimitConstraint *limit = (bRotLimitConstraint *)curcon->data;
|
||||
float local_mat[4][4], imat[4][4];
|
||||
|
||||
bConstraintOb cob = {.depsgraph = NULL, .scene = NULL, .ob = ob, .pchan = pchan};
|
||||
|
||||
float min_vec[3], max_vec[3];
|
||||
|
||||
min_vec[0] = limit->xmin;
|
||||
@@ -605,7 +606,7 @@ static void updateDuplicateLocRotConstraintSettings(Object *ob,
|
||||
unit_m4(local_mat);
|
||||
|
||||
BKE_constraint_mat_convertspace(
|
||||
ob, pchan, local_mat, curcon->ownspace, CONSTRAINT_SPACE_LOCAL, false);
|
||||
ob, pchan, local_mat, &cob, curcon->ownspace, CONSTRAINT_SPACE_LOCAL, false);
|
||||
|
||||
if (curcon->type == CONSTRAINT_TYPE_ROTLIMIT) {
|
||||
/* Zero out any location translation */
|
||||
@@ -656,9 +657,11 @@ static void updateDuplicateTransformConstraintSettings(Object *ob,
|
||||
|
||||
float target_mat[4][4], own_mat[4][4], imat[4][4];
|
||||
|
||||
bConstraintOb cob = {.depsgraph = NULL, .scene = NULL, .ob = ob, .pchan = pchan};
|
||||
|
||||
unit_m4(own_mat);
|
||||
BKE_constraint_mat_convertspace(
|
||||
ob, pchan, own_mat, curcon->ownspace, CONSTRAINT_SPACE_LOCAL, false);
|
||||
ob, pchan, own_mat, &cob, curcon->ownspace, CONSTRAINT_SPACE_LOCAL, false);
|
||||
|
||||
/* ###Source map mirroring### */
|
||||
float old_min, old_max;
|
||||
@@ -716,7 +719,7 @@ static void updateDuplicateTransformConstraintSettings(Object *ob,
|
||||
bPoseChannel *target_pchan = BKE_pose_channel_find_name(ob->pose, trans->subtarget);
|
||||
unit_m4(target_mat);
|
||||
BKE_constraint_mat_convertspace(
|
||||
ob, target_pchan, target_mat, curcon->tarspace, CONSTRAINT_SPACE_LOCAL, false);
|
||||
ob, target_pchan, target_mat, &cob, curcon->tarspace, CONSTRAINT_SPACE_LOCAL, false);
|
||||
|
||||
invert_m4_m4(imat, target_mat);
|
||||
/* convert values into local object space */
|
||||
@@ -826,7 +829,7 @@ static void updateDuplicateConstraintSettings(EditBone *dup_bone, EditBone *orig
|
||||
for (curcon = conlist->first; curcon; curcon = curcon->next) {
|
||||
switch (curcon->type) {
|
||||
case CONSTRAINT_TYPE_ACTION:
|
||||
updateDuplicateActionConstraintSettings(dup_bone, orig_bone, ob, curcon);
|
||||
updateDuplicateActionConstraintSettings(dup_bone, orig_bone, ob, pchan, curcon);
|
||||
break;
|
||||
case CONSTRAINT_TYPE_KINEMATIC:
|
||||
updateDuplicateKinematicConstraintSettings(curcon);
|
||||
|
@@ -307,8 +307,10 @@ typedef struct bSameVolumeConstraint {
|
||||
/* Copy Transform Constraint */
|
||||
typedef struct bTransLikeConstraint {
|
||||
struct Object *tar;
|
||||
int flag;
|
||||
char mix_mode;
|
||||
char _pad[7];
|
||||
char split_mode;
|
||||
char _pad[2];
|
||||
/** MAX_ID_NAME-2. */
|
||||
char subtarget[64];
|
||||
} bTransLikeConstraint;
|
||||
@@ -725,6 +727,10 @@ typedef enum eBConstraint_SpaceTypes {
|
||||
CONSTRAINT_SPACE_POSE = 2,
|
||||
/** For posechannels - local with parent. */
|
||||
CONSTRAINT_SPACE_PARLOCAL = 3,
|
||||
/** For posechannels - local converted to the pose orientation. */
|
||||
CONSTRAINT_SPACE_ABSLOCAL = 6,
|
||||
/** For posechannels - local converted to the owner bone orientation. */
|
||||
CONSTRAINT_SPACE_OWNLOCAL = 7,
|
||||
/** For files from between 2.43-2.46 (should have been parlocal). */
|
||||
CONSTRAINT_SPACE_INVALID = 4, /* do not exchange for anything! */
|
||||
} eBConstraint_SpaceTypes;
|
||||
@@ -795,6 +801,12 @@ typedef enum eCopyScale_Flags {
|
||||
SIZELIKE_UNIFORM = (1 << 5),
|
||||
} eCopyScale_Flags;
|
||||
|
||||
/* bTransLikeConstraint.flag */
|
||||
typedef enum eCopyTransforms_Flags {
|
||||
/* Invert the transformation matrix. */
|
||||
TRANSLIKE_INVERT = (1 << 0),
|
||||
} eCopyTransforms_Flags;
|
||||
|
||||
/* bTransLikeConstraint.mix_mode */
|
||||
typedef enum eCopyTransforms_MixMode {
|
||||
/* Replace rotation channel values. */
|
||||
@@ -805,6 +817,16 @@ typedef enum eCopyTransforms_MixMode {
|
||||
TRANSLIKE_MIX_AFTER = 2,
|
||||
} eCopyTransforms_MixMode;
|
||||
|
||||
/* bTransLikeConstraint.split_mode */
|
||||
typedef enum eCopyTransforms_SplitMode {
|
||||
/* Replace rotation channel values. */
|
||||
TRANSLIKE_SPLIT_SCALE = 0,
|
||||
/* Handle as separate location, rotation and scale. */
|
||||
TRANSLIKE_SPLIT_ALL = 1,
|
||||
/* Handle as a single matrix. */
|
||||
TRANSLIKE_SPLIT_NONE = 2,
|
||||
} eCopyTransforms_SplitMode;
|
||||
|
||||
/* bTransformConstraint.to/from */
|
||||
typedef enum eTransform_ToFrom {
|
||||
TRANS_LOCATION = 0,
|
||||
|
@@ -218,6 +218,18 @@ static const EnumPropertyItem target_space_pchan_items[] = {
|
||||
"Local Space",
|
||||
"The transformation of the target is evaluated relative to its local "
|
||||
"coordinate system"},
|
||||
{CONSTRAINT_SPACE_ABSLOCAL,
|
||||
"ABSOLUTE_LOCAL",
|
||||
0,
|
||||
"Absolute Local Space",
|
||||
"The local transformation of the target bone is evaluated relative to its local "
|
||||
"coordinate system, as if the bone had zero world space rotation in its rest pose"},
|
||||
{CONSTRAINT_SPACE_OWNLOCAL,
|
||||
"OWNER_LOCAL",
|
||||
0,
|
||||
"Owner Local Space",
|
||||
"The local transformation of the target bone is evaluated relative to its local coordinate "
|
||||
"system, as if the target and owner bones had the same orientation in their rest pose"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
@@ -243,6 +255,12 @@ static const EnumPropertyItem owner_space_pchan_items[] = {
|
||||
0,
|
||||
"Local Space",
|
||||
"The constraint is applied relative to the local coordinate system of the object"},
|
||||
{CONSTRAINT_SPACE_ABSLOCAL,
|
||||
"ABSOLUTE_LOCAL",
|
||||
0,
|
||||
"Absolute Local Space",
|
||||
"The constraint is applied relative to the local coordinate system of the bone, "
|
||||
"as if the owner bone had zero world space rotation in its rest pose"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
@@ -1599,14 +1617,32 @@ static void rna_def_constraint_transform_like(BlenderRNA *brna)
|
||||
"BEFORE",
|
||||
0,
|
||||
"Before Original",
|
||||
"Apply copied transformation before original, as if the constraint target is a parent. "
|
||||
"Scale is handled specially to avoid creating shear"},
|
||||
"Apply copied transformation before original, as if the constraint target is a parent."},
|
||||
{TRANSLIKE_MIX_AFTER,
|
||||
"AFTER",
|
||||
0,
|
||||
"After Original",
|
||||
"Apply copied transformation after original, as if the constraint target is a child. "
|
||||
"Scale is handled specially to avoid creating shear"},
|
||||
"Apply copied transformation after original, as if the constraint target is a child."},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem split_mode_items[] = {
|
||||
{TRANSLIKE_SPLIT_SCALE,
|
||||
"SCALE",
|
||||
0,
|
||||
"Split Scale",
|
||||
"Handle scale specially to avoid creating shear"},
|
||||
{TRANSLIKE_SPLIT_ALL,
|
||||
"ALL",
|
||||
0,
|
||||
"Split All",
|
||||
"Separately process location, rotation and scale, similar to a sequence "
|
||||
"of three separate Copy constraints"},
|
||||
{TRANSLIKE_SPLIT_NONE,
|
||||
"NONE",
|
||||
0,
|
||||
"No Split (Allows Shear)",
|
||||
"Treat the transformation as a single unit, using simple matrix math"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
@@ -1624,6 +1660,11 @@ static void rna_def_constraint_transform_like(BlenderRNA *brna)
|
||||
|
||||
RNA_define_lib_overridable(true);
|
||||
|
||||
prop = RNA_def_property(srna, "invert", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", TRANSLIKE_INVERT);
|
||||
RNA_def_property_ui_text(prop, "Invert", "Invert the copied transformation");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
|
||||
|
||||
prop = RNA_def_property(srna, "mix_mode", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "mix_mode");
|
||||
RNA_def_property_enum_items(prop, mix_mode_items);
|
||||
@@ -1631,6 +1672,13 @@ static void rna_def_constraint_transform_like(BlenderRNA *brna)
|
||||
prop, "Mix Mode", "Specify how the copied and existing transformations are combined");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
|
||||
|
||||
prop = RNA_def_property(srna, "split_mode", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "split_mode");
|
||||
RNA_def_property_enum_items(prop, split_mode_items);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Split Mode", "Specify how the location, rotation and scale components are handled");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
|
||||
|
||||
RNA_define_lib_overridable(false);
|
||||
}
|
||||
|
||||
|
@@ -58,6 +58,11 @@ static const EnumPropertyItem space_items[] = {
|
||||
"Local With Parent",
|
||||
"The rest pose local space of a bone (thus matrix includes parent transforms)"},
|
||||
{CONSTRAINT_SPACE_LOCAL, "LOCAL", 0, "Local Space", "The local space of an object/bone"},
|
||||
{CONSTRAINT_SPACE_ABSLOCAL,
|
||||
"ABSOLUTE_LOCAL",
|
||||
0,
|
||||
"Absolute Local Space",
|
||||
"The local space of an object/bone, as if it had zero world space rotation in rest pose"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
@@ -305,7 +310,7 @@ static void rna_Object_mat_convert_space(Object *ob,
|
||||
|
||||
/* Error in case of invalid from/to values when pchan is NULL */
|
||||
if (pchan == NULL) {
|
||||
if (ELEM(from, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_PARLOCAL)) {
|
||||
if (ELEM(from, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_PARLOCAL, CONSTRAINT_SPACE_ABSLOCAL)) {
|
||||
const char *identifier = NULL;
|
||||
RNA_enum_identifier(space_items, from, &identifier);
|
||||
BKE_reportf(reports,
|
||||
@@ -314,7 +319,7 @@ static void rna_Object_mat_convert_space(Object *ob,
|
||||
identifier);
|
||||
return;
|
||||
}
|
||||
if (ELEM(to, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_PARLOCAL)) {
|
||||
if (ELEM(to, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_PARLOCAL, CONSTRAINT_SPACE_ABSLOCAL)) {
|
||||
const char *identifier = NULL;
|
||||
RNA_enum_identifier(space_items, to, &identifier);
|
||||
BKE_reportf(reports,
|
||||
@@ -325,7 +330,7 @@ static void rna_Object_mat_convert_space(Object *ob,
|
||||
}
|
||||
}
|
||||
|
||||
BKE_constraint_mat_convertspace(ob, pchan, (float(*)[4])mat_ret, from, to, false);
|
||||
BKE_constraint_mat_convertspace(ob, pchan, (float(*)[4])mat_ret, NULL, from, to, false);
|
||||
}
|
||||
|
||||
static void rna_Object_calc_matrix_camera(Object *ob,
|
||||
|
Reference in New Issue
Block a user