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:
Diffstat (limited to 'source/blender/blenkernel/intern/constraint.c')
-rw-r--r--source/blender/blenkernel/intern/constraint.c496
1 files changed, 266 insertions, 230 deletions
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 0441e9c9d00..57e5630da19 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -36,6 +36,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
+#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_editVert.h"
@@ -73,10 +74,6 @@
#include "BPY_extern.h"
#endif
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
@@ -259,7 +256,7 @@ void constraint_mat_convertspace (Object *ob, bPoseChannel *pchan, float mat[][4
/* construct offs_bone the same way it is done in armature.c */
copy_m4_m3(offs_bone, pchan->bone->bone_mat);
- VECCOPY(offs_bone[3], pchan->bone->head);
+ copy_v3_v3(offs_bone[3], pchan->bone->head);
offs_bone[3][1]+= pchan->bone->parent->length;
if (pchan->bone->flag & BONE_HINGE) {
@@ -270,7 +267,7 @@ void constraint_mat_convertspace (Object *ob, bPoseChannel *pchan, float mat[][4
copy_m4_m4(tmat, pchan->bone->parent->arm_mat);
/* the location of actual parent transform */
- VECCOPY(tmat[3], offs_bone[3]);
+ copy_v3_v3(tmat[3], offs_bone[3]);
offs_bone[3][0]= offs_bone[3][1]= offs_bone[3][2]= 0.0f;
mul_m4_v3(pchan->parent->pose_mat, tmat[3]);
@@ -312,7 +309,7 @@ void constraint_mat_convertspace (Object *ob, bPoseChannel *pchan, float mat[][4
/* construct offs_bone the same way it is done in armature.c */
copy_m4_m3(offs_bone, pchan->bone->bone_mat);
- VECCOPY(offs_bone[3], pchan->bone->head);
+ copy_v3_v3(offs_bone[3], pchan->bone->head);
offs_bone[3][1]+= pchan->bone->parent->length;
if (pchan->bone->flag & BONE_HINGE) {
@@ -323,8 +320,8 @@ void constraint_mat_convertspace (Object *ob, bPoseChannel *pchan, float mat[][4
copy_m4_m4(tmat, pchan->bone->parent->arm_mat);
/* the location of actual parent transform */
- VECCOPY(tmat[3], offs_bone[3]);
- offs_bone[3][0]= offs_bone[3][1]= offs_bone[3][2]= 0.0f;
+ copy_v3_v3(tmat[3], offs_bone[3]);
+ zero_v3(offs_bone[3]);
mul_m4_v3(pchan->parent->pose_mat, tmat[3]);
mul_m4_m4m4(diff_mat, offs_bone, tmat);
@@ -403,7 +400,7 @@ static void contarget_get_mesh_mat (Scene *scene, Object *ob, char *substring, f
DerivedMesh *dm = NULL;
Mesh *me= ob->data;
EditMesh *em = BKE_mesh_get_editmesh(me);
- float vec[3] = {0.0f, 0.0f, 0.0f}, tvec[3];
+ float vec[3] = {0.0f, 0.0f, 0.0f};
float normal[3] = {0.0f, 0.0f, 0.0f}, plane[3];
float imat[3][3], tmat[3][3];
int dgroup;
@@ -451,8 +448,8 @@ static void contarget_get_mesh_mat (Scene *scene, Object *ob, char *substring, f
if (dvert[i].dw[j].def_nr == dgroup) {
dm->getVertCo(dm, i, co);
dm->getVertNo(dm, i, nor);
- add_v3_v3v3(vec, vec, co);
- add_v3_v3v3(normal, normal, nor);
+ add_v3_v3(vec, co);
+ add_v3_v3(normal, nor);
count++;
break;
}
@@ -480,9 +477,9 @@ static void contarget_get_mesh_mat (Scene *scene, Object *ob, char *substring, f
mul_m3_v3(tmat, normal);
normalize_v3(normal);
- VECCOPY(plane, tmat[1]);
+ copy_v3_v3(plane, tmat[1]);
- VECCOPY(tmat[2], normal);
+ copy_v3_v3(tmat[2], normal);
cross_v3_v3v3(tmat[0], normal, plane);
cross_v3_v3v3(tmat[1], tmat[2], tmat[0]);
@@ -491,8 +488,7 @@ static void contarget_get_mesh_mat (Scene *scene, Object *ob, char *substring, f
/* apply the average coordinate as the new location */
- mul_v3_m4v3(tvec, ob->obmat, vec);
- VECCOPY(mat[3], tvec);
+ mul_v3_m4v3(mat[3], ob->obmat, vec);
}
}
@@ -539,7 +535,7 @@ static void contarget_get_lattice_mat (Object *ob, char *substring, float mat[][
else
memcpy(tvec, bp->vec, 3*sizeof(float));
- add_v3_v3v3(vec, vec, tvec);
+ add_v3_v3(vec, tvec);
grouped++;
break;
@@ -557,7 +553,7 @@ static void contarget_get_lattice_mat (Object *ob, char *substring, float mat[][
mul_v3_m4v3(tvec, ob->obmat, vec);
/* copy new location to matrix */
- VECCOPY(mat[3], tvec);
+ copy_v3_v3(mat[3], tvec);
}
/* generic function to get the appropriate matrix for most target cases */
@@ -822,13 +818,13 @@ static void childof_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
copy_m4_m4(invmat, data->invmat);
/* extract components of both matrices */
- VECCOPY(loc, ct->matrix[3]);
- mat4_to_eulO( eul, ct->rotOrder,ct->matrix);
- mat4_to_size( size,ct->matrix);
+ copy_v3_v3(loc, ct->matrix[3]);
+ mat4_to_eulO(eul, ct->rotOrder, ct->matrix);
+ mat4_to_size(size, ct->matrix);
- VECCOPY(loco, invmat[3]);
- mat4_to_eulO( eulo, cob->rotOrder,invmat);
- mat4_to_size( sizo,invmat);
+ copy_v3_v3(loco, invmat[3]);
+ mat4_to_eulO(eulo, cob->rotOrder, invmat);
+ mat4_to_size(sizo, invmat);
/* disable channels not enabled */
if (!(data->flag & CHILDOF_LOCX)) loc[0]= loco[0]= 0.0f;
@@ -943,9 +939,8 @@ static void vectomat (float *vec, float *target_up, short axis, short upflag, sh
float right[3];
float neg = -1;
int right_index;
-
- copy_v3_v3(n, vec);
- if (normalize_v3(n) == 0.0) {
+
+ if (normalize_v3_v3(n, vec) == 0.0) {
n[0] = 0.0;
n[1] = 0.0;
n[2] = 1.0;
@@ -956,9 +951,7 @@ static void vectomat (float *vec, float *target_up, short axis, short upflag, sh
/* n specifies the transformation of the track axis */
if (flags & TARGET_Z_UP) {
/* target Z axis is the global up axis */
- u[0] = target_up[0];
- u[1] = target_up[1];
- u[2] = target_up[2];
+ copy_v3_v3(u, target_up);
}
else {
/* world Z axis is the global up axis */
@@ -991,20 +984,13 @@ static void vectomat (float *vec, float *target_up, short axis, short upflag, sh
m[right_index][1] = neg * right[1];
m[right_index][2] = neg * right[2];
- m[upflag][0] = proj[0];
- m[upflag][1] = proj[1];
- m[upflag][2] = proj[2];
+ copy_v3_v3(m[upflag], proj);
- m[axis][0] = n[0];
- m[axis][1] = n[1];
- m[axis][2] = n[2];
+ copy_v3_v3(m[axis], n);
}
/* identity matrix - don't do anything if the two axes are the same */
else {
- m[0][0]= m[1][1]= m[2][2]= 1.0;
- m[0][1]= m[0][2]= 0.0;
- m[1][0]= m[1][2]= 0.0;
- m[2][0]= m[2][1]= 0.0;
+ unit_m3(m);
}
}
@@ -1020,7 +1006,7 @@ static void trackto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
float tmat[4][4];
/* Get size property, since ob->size is only the object's own relative size, not its global one */
- mat4_to_size( size,cob->matrix);
+ mat4_to_size(size, cob->matrix);
/* Clear the object's rotation */
cob->matrix[0][0]=size[0];
@@ -1130,10 +1116,9 @@ static void kinematic_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstra
else {
float vec[3];
/* move grabtarget into world space */
- VECCOPY(vec, data->grabtarget);
- mul_m4_v3(ob->obmat, vec);
+ mul_v3_m4v3(vec, ob->obmat, data->grabtarget);
copy_m4_m4(ct->matrix, ob->obmat);
- VECCOPY(ct->matrix[3], vec);
+ copy_v3_v3(ct->matrix[3], vec);
}
}
else
@@ -1246,7 +1231,7 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr
curvetime= data->offset_fac;
}
- if ( where_on_path(ct->tar, curvetime, vec, dir, NULL, &radius) ) {
+ if ( where_on_path(ct->tar, curvetime, vec, dir, NULL, &radius, NULL) ) {
if (data->followflag & FOLLOWPATH_FOLLOW) {
vec_to_quat(quat, dir, (short)data->trackflag, (short)data->upflag);
@@ -1268,7 +1253,7 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr
copy_m4_m4(totmat, rmat);
}
- VECCOPY(totmat[3], vec);
+ copy_v3_v3(totmat[3], vec);
mul_serie_m4(ct->matrix, ct->tar->obmat, totmat, NULL, NULL, NULL, NULL, NULL, NULL);
}
@@ -1387,10 +1372,10 @@ static void rotlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *t
float eul[3];
float size[3];
- VECCOPY(loc, cob->matrix[3]);
- mat4_to_size( size,cob->matrix);
+ copy_v3_v3(loc, cob->matrix[3]);
+ mat4_to_size(size, cob->matrix);
- mat4_to_eulO( eul, cob->rotOrder,cob->matrix);
+ mat4_to_eulO(eul, cob->rotOrder, cob->matrix);
/* constraint data uses radians internally */
@@ -1548,7 +1533,7 @@ static void loclike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
float offset[3] = {0.0f, 0.0f, 0.0f};
if (data->flag & LOCLIKE_OFFSET)
- VECCOPY(offset, cob->matrix[3]);
+ copy_v3_v3(offset, cob->matrix[3]);
if (data->flag & LOCLIKE_X) {
cob->matrix[3][0] = ct->matrix[3][0];
@@ -1640,18 +1625,18 @@ static void rotlike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
float eul[3], obeul[3];
float size[3];
- VECCOPY(loc, cob->matrix[3]);
- mat4_to_size( size,cob->matrix);
+ copy_v3_v3(loc, cob->matrix[3]);
+ mat4_to_size(size, cob->matrix);
/* to allow compatible rotations, must get both rotations in the order of the owner... */
- mat4_to_eulO( eul, cob->rotOrder,ct->matrix);
- mat4_to_eulO( obeul, cob->rotOrder,cob->matrix);
+ mat4_to_eulO(eul, cob->rotOrder, ct->matrix);
+ mat4_to_eulO(obeul, cob->rotOrder, cob->matrix);
if ((data->flag & ROTLIKE_X)==0)
eul[0] = obeul[0];
else {
if (data->flag & ROTLIKE_OFFSET)
- rotate_eulO(eul, cob->rotOrder, 'x', obeul[0]);
+ rotate_eulO(eul, cob->rotOrder, 'X', obeul[0]);
if (data->flag & ROTLIKE_X_INVERT)
eul[0] *= -1;
@@ -1661,7 +1646,7 @@ static void rotlike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
eul[1] = obeul[1];
else {
if (data->flag & ROTLIKE_OFFSET)
- rotate_eulO(eul, cob->rotOrder, 'y', obeul[1]);
+ rotate_eulO(eul, cob->rotOrder, 'Y', obeul[1]);
if (data->flag & ROTLIKE_Y_INVERT)
eul[1] *= -1;
@@ -1671,7 +1656,7 @@ static void rotlike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
eul[2] = obeul[2];
else {
if (data->flag & ROTLIKE_OFFSET)
- rotate_eulO(eul, cob->rotOrder, 'z', obeul[2]);
+ rotate_eulO(eul, cob->rotOrder, 'Z', obeul[2]);
if (data->flag & ROTLIKE_Z_INVERT)
eul[2] *= -1;
@@ -1871,29 +1856,29 @@ static void samevolume_evaluate (bConstraint *con, bConstraintOb *cob, ListBase
{
bSameVolumeConstraint *data= con->data;
+ float volume = data->volume;
+ float fac = 1.0f;
float obsize[3];
- float volume=data->volume;
mat4_to_size(obsize, cob->matrix);
-
+
+ /* calculate normalising scale factor for non-essential values */
+ if (obsize[data->flag] != 0)
+ fac = sqrt(volume / obsize[data->flag]) / obsize[data->flag];
+
+ /* apply scaling factor to the channels not being kept */
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]);
- }
+ mul_v3_fl(cob->matrix[1], fac);
+ mul_v3_fl(cob->matrix[2], fac);
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]);
- }
+ mul_v3_fl(cob->matrix[0], fac);
+ mul_v3_fl(cob->matrix[2], fac);
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]);
- }
+ mul_v3_fl(cob->matrix[0], fac);
+ mul_v3_fl(cob->matrix[1], fac);
break;
}
}
@@ -1983,8 +1968,10 @@ static void pycon_id_looper (bConstraint *con, ConstraintIDFunc func, void *user
/* Whether this approach is maintained remains to be seen (aligorith) */
static void pycon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
{
+#ifndef DISABLE_PYTHON
bPythonConstraint *data= con->data;
-
+#endif
+
if (VALID_CONS_TARGET(ct)) {
/* special exception for curves - depsgraph issues */
if (ct->tar->type == OB_CURVE) {
@@ -2140,7 +2127,7 @@ static void actcon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraint
}
else {
/* extract location */
- VECCOPY(vec, tempmat[3]);
+ copy_v3_v3(vec, tempmat[3]);
axis= data->type - 20;
}
@@ -2296,10 +2283,7 @@ static void locktrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
normalize_v3(totmat[1]);
/* the x axis is fixed */
- totmat[0][0] = cob->matrix[0][0];
- totmat[0][1] = cob->matrix[0][1];
- totmat[0][2] = cob->matrix[0][2];
- normalize_v3(totmat[0]);
+ normalize_v3_v3(totmat[0], cob->matrix[0]);
/* the z axis gets mapped onto a third orthogonal vector */
cross_v3_v3v3(totmat[2], totmat[0], totmat[1]);
@@ -2313,10 +2297,7 @@ static void locktrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
normalize_v3(totmat[2]);
/* the x axis is fixed */
- totmat[0][0] = cob->matrix[0][0];
- totmat[0][1] = cob->matrix[0][1];
- totmat[0][2] = cob->matrix[0][2];
- normalize_v3(totmat[0]);
+ normalize_v3_v3(totmat[0], cob->matrix[0]);
/* the z axis gets mapped onto a third orthogonal vector */
cross_v3_v3v3(totmat[1], totmat[2], totmat[0]);
@@ -2331,10 +2312,7 @@ static void locktrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
negate_v3(totmat[1]);
/* the x axis is fixed */
- totmat[0][0] = cob->matrix[0][0];
- totmat[0][1] = cob->matrix[0][1];
- totmat[0][2] = cob->matrix[0][2];
- normalize_v3(totmat[0]);
+ normalize_v3_v3(totmat[0], cob->matrix[0]);
/* the z axis gets mapped onto a third orthogonal vector */
cross_v3_v3v3(totmat[2], totmat[0], totmat[1]);
@@ -2349,10 +2327,7 @@ static void locktrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
negate_v3(totmat[2]);
/* the x axis is fixed */
- totmat[0][0] = cob->matrix[0][0];
- totmat[0][1] = cob->matrix[0][1];
- totmat[0][2] = cob->matrix[0][2];
- normalize_v3(totmat[0]);
+ normalize_v3_v3(totmat[0], cob->matrix[0]);
/* the z axis gets mapped onto a third orthogonal vector */
cross_v3_v3v3(totmat[1], totmat[2], totmat[0]);
@@ -2360,9 +2335,7 @@ static void locktrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
break;
default:
{
- totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
- totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
- totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
+ unit_m3(totmat);
}
break;
}
@@ -2379,11 +2352,8 @@ static void locktrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
normalize_v3(totmat[0]);
/* the y axis is fixed */
- totmat[1][0] = cob->matrix[1][0];
- totmat[1][1] = cob->matrix[1][1];
- totmat[1][2] = cob->matrix[1][2];
- normalize_v3(totmat[1]);
-
+ normalize_v3_v3(totmat[1], cob->matrix[1]);
+
/* the z axis gets mapped onto a third orthogonal vector */
cross_v3_v3v3(totmat[2], totmat[0], totmat[1]);
}
@@ -2396,10 +2366,7 @@ static void locktrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
normalize_v3(totmat[2]);
/* the y axis is fixed */
- totmat[1][0] = cob->matrix[1][0];
- totmat[1][1] = cob->matrix[1][1];
- totmat[1][2] = cob->matrix[1][2];
- normalize_v3(totmat[1]);
+ normalize_v3_v3(totmat[1], cob->matrix[1]);
/* the z axis gets mapped onto a third orthogonal vector */
cross_v3_v3v3(totmat[0], totmat[1], totmat[2]);
@@ -2414,10 +2381,7 @@ static void locktrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
negate_v3(totmat[0]);
/* the y axis is fixed */
- totmat[1][0] = cob->matrix[1][0];
- totmat[1][1] = cob->matrix[1][1];
- totmat[1][2] = cob->matrix[1][2];
- normalize_v3(totmat[1]);
+ normalize_v3_v3(totmat[1], cob->matrix[1]);
/* the z axis gets mapped onto a third orthogonal vector */
cross_v3_v3v3(totmat[2], totmat[0], totmat[1]);
@@ -2432,10 +2396,7 @@ static void locktrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
negate_v3(totmat[2]);
/* the y axis is fixed */
- totmat[1][0] = cob->matrix[1][0];
- totmat[1][1] = cob->matrix[1][1];
- totmat[1][2] = cob->matrix[1][2];
- normalize_v3(totmat[1]);
+ normalize_v3_v3(totmat[1], cob->matrix[1]);
/* the z axis gets mapped onto a third orthogonal vector */
cross_v3_v3v3(totmat[0], totmat[1], totmat[2]);
@@ -2443,9 +2404,7 @@ static void locktrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
break;
default:
{
- totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
- totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
- totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
+ unit_m3(totmat);
}
break;
}
@@ -2462,10 +2421,7 @@ static void locktrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
normalize_v3(totmat[0]);
/* the z axis is fixed */
- totmat[2][0] = cob->matrix[2][0];
- totmat[2][1] = cob->matrix[2][1];
- totmat[2][2] = cob->matrix[2][2];
- normalize_v3(totmat[2]);
+ normalize_v3_v3(totmat[2], cob->matrix[2]);
/* the x axis gets mapped onto a third orthogonal vector */
cross_v3_v3v3(totmat[1], totmat[2], totmat[0]);
@@ -2479,10 +2435,7 @@ static void locktrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
normalize_v3(totmat[1]);
/* the z axis is fixed */
- totmat[2][0] = cob->matrix[2][0];
- totmat[2][1] = cob->matrix[2][1];
- totmat[2][2] = cob->matrix[2][2];
- normalize_v3(totmat[2]);
+ normalize_v3_v3(totmat[2], cob->matrix[2]);
/* the x axis gets mapped onto a third orthogonal vector */
cross_v3_v3v3(totmat[0], totmat[1], totmat[2]);
@@ -2497,10 +2450,7 @@ static void locktrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
negate_v3(totmat[0]);
/* the z axis is fixed */
- totmat[2][0] = cob->matrix[2][0];
- totmat[2][1] = cob->matrix[2][1];
- totmat[2][2] = cob->matrix[2][2];
- normalize_v3(totmat[2]);
+ normalize_v3_v3(totmat[2], cob->matrix[2]);
/* the x axis gets mapped onto a third orthogonal vector */
cross_v3_v3v3(totmat[1], totmat[2], totmat[0]);
@@ -2515,10 +2465,7 @@ static void locktrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
negate_v3(totmat[1]);
/* the z axis is fixed */
- totmat[2][0] = cob->matrix[2][0];
- totmat[2][1] = cob->matrix[2][1];
- totmat[2][2] = cob->matrix[2][2];
- normalize_v3(totmat[2]);
+ normalize_v3_v3(totmat[2], cob->matrix[2]);
/* the x axis gets mapped onto a third orthogonal vector */
cross_v3_v3v3(totmat[0], totmat[1], totmat[2]);
@@ -2526,9 +2473,7 @@ static void locktrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
break;
default:
{
- totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
- totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
- totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
+ unit_m3(totmat);
}
break;
}
@@ -2536,19 +2481,13 @@ static void locktrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
break;
default:
{
- totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
- totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
- totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
+ unit_m3(totmat);
}
break;
}
/* Block to keep matrix heading */
- tmpmat[0][0] = cob->matrix[0][0];tmpmat[0][1] = cob->matrix[0][1];tmpmat[0][2] = cob->matrix[0][2];
- tmpmat[1][0] = cob->matrix[1][0];tmpmat[1][1] = cob->matrix[1][1];tmpmat[1][2] = cob->matrix[1][2];
- tmpmat[2][0] = cob->matrix[2][0];tmpmat[2][1] = cob->matrix[2][1];tmpmat[2][2] = cob->matrix[2][2];
- normalize_v3(tmpmat[0]);
- normalize_v3(tmpmat[1]);
- normalize_v3(tmpmat[2]);
+ copy_m3_m4(tmpmat, cob->matrix);
+ normalize_m3(tmpmat);
invert_m3_m3(invmat, tmpmat);
mul_m3_m3m3(tmpmat, totmat, invmat);
totmat[0][0] = tmpmat[0][0];totmat[0][1] = tmpmat[0][1];totmat[0][2] = tmpmat[0][2];
@@ -2561,9 +2500,7 @@ static void locktrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
totmat[1][0],totmat[1][1],totmat[1][2],
totmat[2][0],totmat[2][1],totmat[2][2]);
if (mdet==0) {
- totmat[0][0] = 1;totmat[0][1] = 0;totmat[0][2] = 0;
- totmat[1][0] = 0;totmat[1][1] = 1;totmat[1][2] = 0;
- totmat[2][0] = 0;totmat[2][1] = 0;totmat[2][2] = 1;
+ unit_m3(totmat);
}
/* apply out transformaton to the object */
@@ -2691,7 +2628,7 @@ static void distlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
interp_v3_v3v3(dvec, ct->matrix[3], cob->matrix[3], sfac);
/* copy new vector onto owner */
- VECCOPY(cob->matrix[3], dvec);
+ copy_v3_v3(cob->matrix[3], dvec);
}
}
}
@@ -2771,19 +2708,13 @@ static void stretchto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
float dist;
/* store scaling before destroying obmat */
- mat4_to_size( size,cob->matrix);
+ mat4_to_size(size, cob->matrix);
/* store X orientation before destroying obmat */
- xx[0] = cob->matrix[0][0];
- xx[1] = cob->matrix[0][1];
- xx[2] = cob->matrix[0][2];
- normalize_v3(xx);
+ normalize_v3_v3(xx, cob->matrix[0]);
/* store Z orientation before destroying obmat */
- zz[0] = cob->matrix[2][0];
- zz[1] = cob->matrix[2][1];
- zz[2] = cob->matrix[2][2];
- normalize_v3(zz);
+ normalize_v3_v3(zz, cob->matrix[2]);
sub_v3_v3v3(vec, cob->matrix[3], ct->matrix[3]);
vec[0] /= size[0];
@@ -2838,9 +2769,7 @@ static void stretchto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
normalize_v3(vec);
/* new Y aligns object target connection*/
- totmat[1][0] = -vec[0];
- totmat[1][1] = -vec[1];
- totmat[1][2] = -vec[2];
+ negate_v3_v3(totmat[1], vec);
switch (data->plane) {
case PLANE_X:
/* build new Z vector */
@@ -2849,16 +2778,11 @@ static void stretchto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
normalize_v3(orth);
/* new Z*/
- totmat[2][0] = orth[0];
- totmat[2][1] = orth[1];
- totmat[2][2] = orth[2];
+ copy_v3_v3(totmat[2], orth);
/* we decided to keep X plane*/
cross_v3_v3v3(xx, orth, vec);
- normalize_v3(xx);
- totmat[0][0] = xx[0];
- totmat[0][1] = xx[1];
- totmat[0][2] = xx[2];
+ normalize_v3_v3(totmat[0], xx);
break;
case PLANE_Z:
/* build new X vector */
@@ -2867,16 +2791,11 @@ static void stretchto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
normalize_v3(orth);
/* new X */
- totmat[0][0] = -orth[0];
- totmat[0][1] = -orth[1];
- totmat[0][2] = -orth[2];
+ negate_v3_v3(totmat[0], orth);
/* we decided to keep Z */
cross_v3_v3v3(zz, orth, vec);
- normalize_v3(zz);
- totmat[2][0] = zz[0];
- totmat[2][1] = zz[1];
- totmat[2][2] = zz[2];
+ normalize_v3_v3(totmat[2], zz);
break;
} /* switch (data->plane) */
@@ -3008,10 +2927,10 @@ static void minmax_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *tar
obmat[3][index] = tarmat[3][index] + data->offset;
if (data->flag & MINMAX_STICKY) {
if (data->flag & MINMAX_STUCK) {
- VECCOPY(obmat[3], data->cache);
+ copy_v3_v3(obmat[3], data->cache);
}
else {
- VECCOPY(data->cache, obmat[3]);
+ copy_v3_v3(data->cache, obmat[3]);
data->flag |= MINMAX_STUCK;
}
}
@@ -3021,7 +2940,7 @@ static void minmax_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *tar
copy_m4_m4(cob->matrix, tmat);
}
else {
- VECCOPY(cob->matrix[3], obmat[3]);
+ copy_v3_v3(cob->matrix[3], obmat[3]);
}
}
else {
@@ -3176,7 +3095,7 @@ static void clampto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
copy_m4_m4(obmat, cob->matrix);
unit_m4(targetMatrix);
- VECCOPY(ownLoc, obmat[3]);
+ copy_v3_v3(ownLoc, obmat[3]);
INIT_MINMAX(curveMin, curveMax)
minmax_object(ct->tar, curveMin, curveMax);
@@ -3263,16 +3182,16 @@ static void clampto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
}
/* 3. position on curve */
- if (where_on_path(ct->tar, curvetime, vec, dir, NULL, NULL) ) {
+ if (where_on_path(ct->tar, curvetime, vec, dir, NULL, NULL, NULL) ) {
unit_m4(totmat);
- VECCOPY(totmat[3], vec);
+ copy_v3_v3(totmat[3], vec);
mul_serie_m4(targetMatrix, ct->tar->obmat, totmat, NULL, NULL, NULL, NULL, NULL, NULL);
}
}
/* obtain final object position */
- VECCOPY(cob->matrix[3], targetMatrix[3]);
+ copy_v3_v3(cob->matrix[3], targetMatrix[3]);
}
}
@@ -3354,7 +3273,7 @@ static void transform_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
mat4_to_size( dvec,ct->matrix);
break;
case 1: /* rotation (convert to degrees first) */
- mat4_to_eulO( dvec, cob->rotOrder,ct->matrix);
+ mat4_to_eulO(dvec, cob->rotOrder, ct->matrix);
for (i=0; i<3; i++)
dvec[i] = (float)(dvec[i] / M_PI * 180);
break;
@@ -3364,9 +3283,9 @@ static void transform_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
}
/* extract components of owner's matrix */
- VECCOPY(loc, cob->matrix[3]);
- mat4_to_eulO( eul, cob->rotOrder,cob->matrix);
- mat4_to_size( size,cob->matrix);
+ copy_v3_v3(loc, cob->matrix[3]);
+ mat4_to_eulO(eul, cob->rotOrder, cob->matrix);
+ mat4_to_size(size, cob->matrix);
/* determine where in range current transforms lie */
if (data->expo) {
@@ -3486,95 +3405,95 @@ static void shrinkwrap_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr
float co[3] = {0.0f, 0.0f, 0.0f};
float no[3] = {0.0f, 0.0f, 0.0f};
float dist;
-
+
SpaceTransform transform;
DerivedMesh *target = object_get_derived_final(cob->scene, ct->tar, CD_MASK_BAREMESH);
BVHTreeRayHit hit;
BVHTreeNearest nearest;
-
+
BVHTreeFromMesh treeData;
- memset( &treeData, 0, sizeof(treeData) );
-
+ memset(&treeData, 0, sizeof(treeData));
+
nearest.index = -1;
nearest.dist = FLT_MAX;
-
+
hit.index = -1;
hit.dist = 100000.0f; //TODO should use FLT_MAX.. but normal projection doenst yet supports it
-
+
unit_m4(ct->matrix);
-
+
if(target != NULL)
{
space_transform_from_matrixs(&transform, cob->matrix, ct->tar->obmat);
-
+
switch(scon->shrinkType)
{
case MOD_SHRINKWRAP_NEAREST_SURFACE:
case MOD_SHRINKWRAP_NEAREST_VERTEX:
-
+
if(scon->shrinkType == MOD_SHRINKWRAP_NEAREST_VERTEX)
bvhtree_from_mesh_verts(&treeData, target, 0.0, 2, 6);
else
bvhtree_from_mesh_faces(&treeData, target, 0.0, 2, 6);
-
+
if(treeData.tree == NULL)
{
fail = TRUE;
break;
}
-
+
space_transform_apply(&transform, co);
-
+
BLI_bvhtree_find_nearest(treeData.tree, co, &nearest, treeData.nearest_callback, &treeData);
dist = len_v3v3(co, nearest.co);
interp_v3_v3v3(co, co, nearest.co, (dist - scon->dist)/dist); /* linear interpolation */
space_transform_invert(&transform, co);
break;
-
+
case MOD_SHRINKWRAP_PROJECT:
if(scon->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_X_AXIS) no[0] = 1.0f;
if(scon->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_Y_AXIS) no[1] = 1.0f;
if(scon->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_Z_AXIS) no[2] = 1.0f;
-
+
if(INPR(no,no) < FLT_EPSILON)
{
fail = TRUE;
break;
}
-
+
normalize_v3(no);
-
-
+
+
bvhtree_from_mesh_faces(&treeData, target, scon->dist, 4, 6);
if(treeData.tree == NULL)
{
fail = TRUE;
break;
}
-
+
if(normal_projection_project_vertex(0, co, no, &transform, treeData.tree, &hit, treeData.raycast_callback, &treeData) == FALSE)
{
fail = TRUE;
break;
}
- VECCOPY(co, hit.co);
+ copy_v3_v3(co, hit.co);
break;
}
-
+
free_bvhtree_from_mesh(&treeData);
-
+
target->release(target);
-
+
if(fail == TRUE)
{
/* Don't move the point */
co[0] = co[1] = co[2] = 0.0f;
}
-
+
/* co is in local object coordinates, change it to global and update target position */
- mul_v3_m4v3(co, cob->matrix, co);
- VECCOPY(ct->matrix[3], co);
+ mul_m4_v3(cob->matrix, co);
+ copy_v3_v3(ct->matrix[3], co);
}
}
}
@@ -3586,7 +3505,7 @@ static void shrinkwrap_evaluate (bConstraint *con, bConstraintOb *cob, ListBase
/* only evaluate if there is a target */
if (VALID_CONS_TARGET(ct))
{
- VECCOPY(cob->matrix[3], ct->matrix[3]);
+ copy_v3_v3(cob->matrix[3], ct->matrix[3]);
}
}
@@ -3670,23 +3589,23 @@ static void damptrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
* - the normalisation step at the end should take care of any unwanted scaling
* left over in the 3x3 matrix we used
*/
- VECCOPY(obvec, track_dir_vecs[data->trackflag]);
+ copy_v3_v3(obvec, track_dir_vecs[data->trackflag]);
mul_mat3_m4_v3(cob->matrix, obvec);
if (normalize_v3(obvec) == 0.0f) {
/* exceptional case - just use the track vector as appropriate */
- VECCOPY(obvec, track_dir_vecs[data->trackflag]);
+ copy_v3_v3(obvec, track_dir_vecs[data->trackflag]);
}
/* find the (unit) direction vector going from the owner to the target */
- VECCOPY(obloc, cob->matrix[3]);
+ copy_v3_v3(obloc, cob->matrix[3]);
sub_v3_v3v3(tarvec, ct->matrix[3], obloc);
if (normalize_v3(tarvec) == 0.0f) {
/* the target is sitting on the owner, so just make them use the same direction vectors */
// FIXME: or would it be better to use the pure direction vector?
- VECCOPY(tarvec, obvec);
- //VECCOPY(tarvec, track_dir_vecs[data->trackflag]);
+ copy_v3_v3(tarvec, obvec);
+ //copy_v3_v3(tarvec, track_dir_vecs[data->trackflag]);
}
/* determine the axis-angle rotation, which represents the smallest possible rotation
@@ -3705,7 +3624,7 @@ static void damptrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
/* construct rotation matrix from the axis-angle rotation found above
* - this call takes care to make sure that the axis provided is a unit vector first
*/
- axis_angle_to_mat3( rmat,raxis, rangle);
+ axis_angle_to_mat3(rmat, raxis, rangle);
/* rotate the owner in the way defined by this rotation matrix, then reapply the location since
* we may have destroyed that in the process of multiplying the matrix
@@ -3714,7 +3633,7 @@ static void damptrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
mul_m4_m3m4(tmat, rmat, cob->matrix); // m1, m3, m2
copy_m4_m4(cob->matrix, tmat);
- VECCOPY(cob->matrix[3], obloc);
+ copy_v3_v3(cob->matrix[3], obloc);
}
}
@@ -3754,6 +3673,13 @@ static void splineik_copy (bConstraint *con, bConstraint *srccon)
dst->points= MEM_dupallocN(src->points);
}
+static void splineik_new_data (void *cdata)
+{
+ bSplineIKConstraint *data= (bSplineIKConstraint *)cdata;
+
+ data->chainlen= 1;
+}
+
static void splineik_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
{
bSplineIKConstraint *data= con->data;
@@ -3818,13 +3744,125 @@ static bConstraintTypeInfo CTI_SPLINEIK = {
NULL, /* relink data */
splineik_id_looper, /* id looper */
splineik_copy, /* copy data */
- NULL, /* new data */
+ splineik_new_data, /* new data */
splineik_get_tars, /* get constraint targets */
splineik_flush_tars, /* flush constraint targets */
splineik_get_tarmat, /* get target matrix */
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 */
+ copy_v3_v3(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.
@@ -3861,6 +3899,7 @@ static void constraints_init_typeinfo () {
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
@@ -3948,17 +3987,6 @@ int remove_constraint (ListBase *list, bConstraint *con)
return 0;
}
-/* Remove the nth constraint from the given constraint stack */
-int remove_constraint_index (ListBase *list, int index)
-{
- bConstraint *con= BLI_findlink(list, index);
-
- if (con)
- return remove_constraint(list, con);
- else
- return 0;
-}
-
/* Remove all the constraints of the specified type from the given constraint stack */
void remove_constraints_type (ListBase *list, short type, short last_only)
{
@@ -4125,7 +4153,7 @@ static void con_extern_cb(bConstraint *con, ID **idpoin, void *userdata)
}
/* duplicate all of the constraints in a constraint stack */
-void copy_constraints (ListBase *dst, const ListBase *src)
+void copy_constraints (ListBase *dst, const ListBase *src, int do_extern)
{
bConstraint *con, *srccon;
@@ -4144,15 +4172,23 @@ void copy_constraints (ListBase *dst, const ListBase *src)
if (cti->copy_data)
cti->copy_data(con, srccon);
- /* go over used ID-links for this constraint to ensure that they are valid for proxies */
- if (cti->id_looper)
- cti->id_looper(con, con_extern_cb, NULL);
+ /* for proxies we dont want to make extern */
+ if (do_extern) {
+ /* go over used ID-links for this constraint to ensure that they are valid for proxies */
+ if (cti->id_looper)
+ cti->id_looper(con, con_extern_cb, NULL);
+ }
}
}
}
/* ......... */
+bConstraint *constraints_findByName(ListBase *list, const char *name)
+{
+ return BLI_findstring(list, name, offsetof(bConstraint, name));
+}
+
/* finds the 'active' constraint in a constraint stack */
bConstraint *constraints_get_active (ListBase *list)
{