246
304
/* pose to world */
247
305
if (to == CONSTRAINT_SPACE_WORLD) {
248
copy_m4_m4(tempmat, mat);
249
mul_m4_m4m4(mat, tempmat, ob->obmat);
306
mult_m4_m4m4(mat, ob->obmat, mat);
251
308
/* pose to local */
252
309
else if (to == CONSTRAINT_SPACE_LOCAL) {
253
310
if (pchan->bone) {
255
float offs_bone[4][4];
257
/* construct offs_bone the same way it is done in armature.c */
258
copy_m4_m3(offs_bone, pchan->bone->bone_mat);
259
VECCOPY(offs_bone[3], pchan->bone->head);
260
offs_bone[3][1]+= pchan->bone->parent->length;
262
if (pchan->bone->flag & BONE_HINGE) {
263
/* pose_mat = par_pose-space_location * chan_mat */
266
/* the rotation of the parent restposition */
267
copy_m4_m4(tmat, pchan->bone->parent->arm_mat);
269
/* the location of actual parent transform */
270
VECCOPY(tmat[3], offs_bone[3]);
271
offs_bone[3][0]= offs_bone[3][1]= offs_bone[3][2]= 0.0f;
272
mul_m4_v3(pchan->parent->pose_mat, tmat[3]);
274
mul_m4_m4m4(diff_mat, offs_bone, tmat);
275
invert_m4_m4(imat, diff_mat);
278
/* pose_mat = par_pose_mat * bone_mat * chan_mat */
279
mul_m4_m4m4(diff_mat, offs_bone, pchan->parent->pose_mat);
280
invert_m4_m4(imat, diff_mat);
284
/* pose_mat = chan_mat * arm_mat */
285
invert_m4_m4(imat, pchan->bone->arm_mat);
288
copy_m4_m4(tempmat, mat);
289
mul_m4_m4m4(mat, tempmat, imat);
311
armature_mat_pose_to_bone(pchan, mat, mat);
312
#if 0 /* XXX Old code, will remove it later. */
313
constraint_pchan_diff_mat(pchan, diff_mat);
315
invert_m4_m4(imat, diff_mat);
316
mult_m4_m4m4(mat, imat, mat);
318
/* override with local location */
319
if ((pchan->parent) && (pchan->bone->flag & BONE_NO_LOCAL_LOCATION)) {
320
armature_mat_pose_to_bone_ex(ob, pchan, pchan->pose_mat, tempmat);
321
copy_v3_v3(mat[3], tempmat[3]);
292
326
/* pose to local with parent */
293
327
else if (to == CONSTRAINT_SPACE_PARLOCAL) {
294
328
if (pchan->bone) {
295
329
invert_m4_m4(imat, pchan->bone->arm_mat);
296
copy_m4_m4(tempmat, mat);
297
mul_m4_m4m4(mat, tempmat, imat);
330
mult_m4_m4m4(mat, imat, mat);
395
415
/* ------------ General Target Matrix Tools ---------- */
397
417
/* function that sets the given matrix based on given vertex group in mesh */
398
static void contarget_get_mesh_mat (Scene *scene, Object *ob, char *substring, float mat[][4])
418
static void contarget_get_mesh_mat (Object *ob, const char *substring, float mat[][4])
400
420
DerivedMesh *dm = NULL;
401
421
Mesh *me= ob->data;
402
EditMesh *em = BKE_mesh_get_editmesh(me);
403
float vec[3] = {0.0f, 0.0f, 0.0f}, tvec[3];
422
BMEditMesh *em = me->edit_btmesh;
423
float vec[3] = {0.0f, 0.0f, 0.0f};
404
424
float normal[3] = {0.0f, 0.0f, 0.0f}, plane[3];
405
425
float imat[3][3], tmat[3][3];
426
const int defgroup= defgroup_name_index(ob, substring);
407
427
short freeDM = 0;
409
429
/* initialize target matrix using target matrix */
410
430
copy_m4_m4(mat, ob->obmat);
412
432
/* get index of vertex group */
413
dgroup = defgroup_name_index(ob, substring);
414
if (dgroup < 0) return;
433
if (defgroup == -1) return;
416
435
/* get DerivedMesh */
418
437
/* target is in editmode, so get a special derived mesh */
419
dm = CDDM_from_editmesh(em, ob->data);
438
dm = CDDM_from_BMEditMesh(em, ob->data, FALSE, FALSE);
423
/* when not in EditMode, use the 'final' derived mesh
424
* - check if the custom data masks for derivedFinal mean that we can just use that
425
* (this is more effficient + sufficient for most cases)
442
/* when not in EditMode, use the 'final' derived mesh, depsgraph
443
* ensures we build with CD_MDEFORMVERT layer
427
if (!(ob->lastDataMask & CD_MASK_MDEFORMVERT)) {
428
dm = mesh_get_derived_final(scene, ob, CD_MASK_MDEFORMVERT);
432
dm = (DerivedMesh *)ob->derivedFinal;
445
dm = (DerivedMesh *)ob->derivedFinal;
435
448
/* only continue if there's a valid DerivedMesh */
437
450
MDeformVert *dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
438
451
int numVerts = dm->getNumVerts(dm);
440
453
float co[3], nor[3];
442
455
/* check that dvert is a valid pointers (just in case) */
457
MDeformVert *dv= dvert;
444
458
/* get the average of all verts with that are in the vertex-group */
445
for (i = 0; i < numVerts; i++) {
446
for (j = 0; j < dvert[i].totweight; j++) {
447
/* does this vertex belong to nominated vertex group? */
448
if (dvert[i].dw[j].def_nr == dgroup) {
449
dm->getVertCo(dm, i, co);
450
dm->getVertNo(dm, i, nor);
452
add_v3_v3(normal, nor);
459
for (i = 0; i < numVerts; i++, dv++) {
460
MDeformWeight *dw= defvert_find_index(dv, defgroup);
461
if (dw && dw->weight != 0.0f) {
462
dm->getVertCo(dm, i, co);
463
dm->getVertNo(dm, i, nor);
465
add_v3_v3(normal, nor);
461
471
/* calculate averages of normal and coordinates */
463
473
mul_v3_fl(vec, 1.0f / count);
809
815
bChildOfConstraint *data= con->data;
810
816
bConstraintTarget *ct= targets->first;
812
818
/* only evaluate if there is a target */
813
819
if (VALID_CONS_TARGET(ct)) {
814
float parmat[4][4], invmat[4][4], tempmat[4][4];
815
float loc[3], eul[3], size[3];
816
float loco[3], eulo[3], sizo[3];
818
/* get offset (parent-inverse) matrix */
819
copy_m4_m4(invmat, data->invmat);
821
/* extract components of both matrices */
822
VECCOPY(loc, ct->matrix[3]);
823
mat4_to_eulO(eul, ct->rotOrder, ct->matrix);
824
mat4_to_size(size, ct->matrix);
826
VECCOPY(loco, invmat[3]);
827
mat4_to_eulO(eulo, cob->rotOrder, invmat);
828
mat4_to_size(sizo, invmat);
830
/* disable channels not enabled */
831
if (!(data->flag & CHILDOF_LOCX)) loc[0]= loco[0]= 0.0f;
832
if (!(data->flag & CHILDOF_LOCY)) loc[1]= loco[1]= 0.0f;
833
if (!(data->flag & CHILDOF_LOCZ)) loc[2]= loco[2]= 0.0f;
834
if (!(data->flag & CHILDOF_ROTX)) eul[0]= eulo[0]= 0.0f;
835
if (!(data->flag & CHILDOF_ROTY)) eul[1]= eulo[1]= 0.0f;
836
if (!(data->flag & CHILDOF_ROTZ)) eul[2]= eulo[2]= 0.0f;
837
if (!(data->flag & CHILDOF_SIZEX)) size[0]= sizo[0]= 1.0f;
838
if (!(data->flag & CHILDOF_SIZEY)) size[1]= sizo[1]= 1.0f;
839
if (!(data->flag & CHILDOF_SIZEZ)) size[2]= sizo[2]= 1.0f;
841
/* make new target mat and offset mat */
842
loc_eulO_size_to_mat4(ct->matrix, loc, eul, size, ct->rotOrder);
843
loc_eulO_size_to_mat4(invmat, loco, eulo, sizo, cob->rotOrder);
845
/* multiply target (parent matrix) by offset (parent inverse) to get
846
* the effect of the parent that will be exherted on the owner
848
mul_m4_m4m4(parmat, invmat, ct->matrix);
850
/* now multiply the parent matrix by the owner matrix to get the
851
* the effect of this constraint (i.e. owner is 'parented' to parent)
853
copy_m4_m4(tempmat, cob->matrix);
854
mul_m4_m4m4(cob->matrix, tempmat, parmat);
822
/* simple matrix parenting */
823
if (data->flag == CHILDOF_ALL) {
825
/* multiply target (parent matrix) by offset (parent inverse) to get
826
* the effect of the parent that will be exherted on the owner
828
mult_m4_m4m4(parmat, ct->matrix, data->invmat);
830
/* now multiply the parent matrix by the owner matrix to get the
831
* the effect of this constraint (i.e. owner is 'parented' to parent)
833
mult_m4_m4m4(cob->matrix, parmat, cob->matrix);
836
float invmat[4][4], tempmat[4][4];
837
float loc[3], eul[3], size[3];
838
float loco[3], eulo[3], sizo[3];
840
/* get offset (parent-inverse) matrix */
841
copy_m4_m4(invmat, data->invmat);
843
/* extract components of both matrices */
844
copy_v3_v3(loc, ct->matrix[3]);
845
mat4_to_eulO(eul, ct->rotOrder, ct->matrix);
846
mat4_to_size(size, ct->matrix);
848
copy_v3_v3(loco, invmat[3]);
849
mat4_to_eulO(eulo, cob->rotOrder, invmat);
850
mat4_to_size(sizo, invmat);
852
/* disable channels not enabled */
853
if (!(data->flag & CHILDOF_LOCX)) loc[0]= loco[0]= 0.0f;
854
if (!(data->flag & CHILDOF_LOCY)) loc[1]= loco[1]= 0.0f;
855
if (!(data->flag & CHILDOF_LOCZ)) loc[2]= loco[2]= 0.0f;
856
if (!(data->flag & CHILDOF_ROTX)) eul[0]= eulo[0]= 0.0f;
857
if (!(data->flag & CHILDOF_ROTY)) eul[1]= eulo[1]= 0.0f;
858
if (!(data->flag & CHILDOF_ROTZ)) eul[2]= eulo[2]= 0.0f;
859
if (!(data->flag & CHILDOF_SIZEX)) size[0]= sizo[0]= 1.0f;
860
if (!(data->flag & CHILDOF_SIZEY)) size[1]= sizo[1]= 1.0f;
861
if (!(data->flag & CHILDOF_SIZEZ)) size[2]= sizo[2]= 1.0f;
863
/* make new target mat and offset mat */
864
loc_eulO_size_to_mat4(ct->matrix, loc, eul, size, ct->rotOrder);
865
loc_eulO_size_to_mat4(invmat, loco, eulo, sizo, cob->rotOrder);
867
/* multiply target (parent matrix) by offset (parent inverse) to get
868
* the effect of the parent that will be exherted on the owner
870
mult_m4_m4m4(parmat, ct->matrix, invmat);
872
/* now multiply the parent matrix by the owner matrix to get the
873
* the effect of this constraint (i.e. owner is 'parented' to parent)
875
copy_m4_m4(tempmat, cob->matrix);
876
mult_m4_m4m4(cob->matrix, parmat, tempmat);
878
/* without this, changes to scale and rotation can change location
879
* of a parentless bone or a disconnected bone. Even though its set
881
if (!(data->flag & CHILDOF_LOCX)) cob->matrix[3][0]= tempmat[3][0];
882
if (!(data->flag & CHILDOF_LOCY)) cob->matrix[3][1]= tempmat[3][1];
883
if (!(data->flag & CHILDOF_LOCZ)) cob->matrix[3][2]= tempmat[3][2];
888
/* XXX note, con->flag should be CONSTRAINT_SPACEONCE for bone-childof, patched in readfile.c */
858
889
static bConstraintTypeInfo CTI_CHILDOF = {
859
890
CONSTRAINT_TYPE_CHILDOF, /* type */
860
891
sizeof(bChildOfConstraint), /* size */
3936
3908
NULL, /* relink data */
3937
3909
pivotcon_id_looper, /* id looper */
3938
3910
NULL, /* copy data */
3939
NULL, /* new data */ // XXX: might be needed to get 'normal' pivot behaviour...
3911
NULL, /* new data */ // XXX: might be needed to get 'normal' pivot behavior...
3940
3912
pivotcon_get_tars, /* get constraint targets */
3941
3913
pivotcon_flush_tars, /* flush constraint targets */
3942
3914
default_get_tarmat, /* get target matrix */
3943
3915
pivotcon_evaluate /* evaluate */
3918
/* ----------- Follow Track ------------- */
3920
static void followtrack_new_data(void *cdata)
3922
bFollowTrackConstraint *data = (bFollowTrackConstraint *)cdata;
3925
data->flag |= FOLLOWTRACK_ACTIVECLIP;
3928
static void followtrack_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
3930
bFollowTrackConstraint *data = con->data;
3932
func(con, (ID**)&data->clip, TRUE, userdata);
3933
func(con, (ID**)&data->camera, FALSE, userdata);
3934
func(con, (ID**)&data->depth_ob, FALSE, userdata);
3937
static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
3939
Scene *scene = cob->scene;
3940
bFollowTrackConstraint *data = con->data;
3941
MovieClip *clip = data->clip;
3942
MovieTracking *tracking;
3943
MovieTrackingTrack *track;
3944
MovieTrackingObject *tracking_object;
3945
Object *camob= data->camera ? data->camera : scene->camera;
3947
if (data->flag & FOLLOWTRACK_ACTIVECLIP)
3950
if (!clip || !data->track[0] || !camob)
3953
tracking = &clip->tracking;
3955
if (data->object[0])
3956
tracking_object = BKE_tracking_named_object(tracking, data->object);
3958
tracking_object = BKE_tracking_get_camera_object(tracking);
3960
if (!tracking_object)
3963
track = BKE_tracking_named_track(tracking, tracking_object, data->track);
3968
if (data->flag & FOLLOWTRACK_USE_3D_POSITION) {
3969
if (track->flag & TRACK_HAS_BUNDLE) {
3970
float obmat[4][4], mat[4][4];
3972
copy_m4_m4(obmat, cob->matrix);
3974
if ((tracking_object->flag & TRACKING_OBJECT_CAMERA)==0) {
3977
copy_m4_m4(mat, camob->obmat);
3979
BKE_tracking_get_interpolated_camera(tracking, tracking_object, scene->r.cfra, imat);
3982
mul_serie_m4(cob->matrix, obmat, mat, imat, NULL, NULL, NULL, NULL, NULL);
3983
translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]);
3986
BKE_get_tracking_mat(cob->scene, camob, mat);
3988
mult_m4_m4m4(cob->matrix, obmat, mat);
3989
translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]);
3994
MovieTrackingMarker *marker;
3995
float vec[3], disp[3], axis[3], mat[4][4];
3996
float aspect= (scene->r.xsch * scene->r.xasp) / (scene->r.ysch * scene->r.yasp);
3999
where_is_object_mat(scene, camob, mat);
4005
mul_v3_m4v3(axis, mat, vec);
4007
/* distance to projection plane */
4008
copy_v3_v3(vec, cob->matrix[3]);
4009
sub_v3_v3(vec, mat[3]);
4010
project_v3_v3v3(disp, vec, axis);
4014
if (len > FLT_EPSILON) {
4015
CameraParams params;
4016
float pos[2], rmat[4][4];
4018
marker = BKE_tracking_get_marker(track, scene->r.cfra);
4020
add_v2_v2v2(pos, marker->pos, track->offset);
4022
camera_params_init(¶ms);
4023
camera_params_from_object(¶ms, camob);
4025
if (params.is_ortho) {
4026
vec[0] = params.ortho_scale * (pos[0] - 0.5f + params.shiftx);
4027
vec[1] = params.ortho_scale * (pos[1] - 0.5f + params.shifty);
4035
mul_v3_m4v3(disp, camob->obmat, vec);
4037
copy_m4_m4(rmat, camob->obmat);
4039
mult_m4_m4m4(cob->matrix, cob->matrix, rmat);
4041
copy_v3_v3(cob->matrix[3], disp);
4044
d= (len * params.sensor_x) / (2.0f * params.lens);
4046
vec[0] = d * (2.0f * (pos[0] + params.shiftx) - 1.0f);
4047
vec[1] = d * (2.0f * (pos[1] + params.shifty) - 1.0f);
4055
mul_v3_m4v3(disp, camob->obmat, vec);
4057
/* apply camera rotation so Z-axis would be co-linear */
4058
copy_m4_m4(rmat, camob->obmat);
4060
mult_m4_m4m4(cob->matrix, cob->matrix, rmat);
4062
copy_v3_v3(cob->matrix[3], disp);
4065
if (data->depth_ob && data->depth_ob->derivedFinal) {
4066
Object *depth_ob = data->depth_ob;
4067
BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh;
4069
float ray_start[3], ray_end[3], ray_nor[3], imat[4][4];
4072
invert_m4_m4(imat, depth_ob->obmat);
4074
mul_v3_m4v3(ray_start, imat, camob->obmat[3]);
4075
mul_v3_m4v3(ray_end, imat, cob->matrix[3]);
4077
sub_v3_v3v3(ray_nor, ray_end, ray_start);
4079
bvhtree_from_mesh_faces(&treeData, depth_ob->derivedFinal, 0.0f, 4, 6);
4084
result = BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_nor, 0.0f, &hit, treeData.raycast_callback, &treeData);
4087
mul_v3_m4v3(cob->matrix[3], depth_ob->obmat, hit.co);
4090
free_bvhtree_from_mesh(&treeData);
4096
static bConstraintTypeInfo CTI_FOLLOWTRACK = {
4097
CONSTRAINT_TYPE_FOLLOWTRACK, /* type */
4098
sizeof(bFollowTrackConstraint), /* size */
4099
"Follow Track", /* name */
4100
"bFollowTrackConstraint", /* struct name */
4101
NULL, /* free data */
4102
NULL, /* relink data */
4103
followtrack_id_looper, /* id looper */
4104
NULL, /* copy data */
4105
followtrack_new_data, /* new data */
4106
NULL, /* get constraint targets */
4107
NULL, /* flush constraint targets */
4108
NULL, /* get target matrix */
4109
followtrack_evaluate /* evaluate */
4112
/* ----------- Camre Solver ------------- */
4114
static void camerasolver_new_data(void *cdata)
4116
bCameraSolverConstraint *data = (bCameraSolverConstraint *)cdata;
4119
data->flag |= CAMERASOLVER_ACTIVECLIP;
4122
static void camerasolver_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
4124
bCameraSolverConstraint *data = con->data;
4126
func(con, (ID**)&data->clip, TRUE, userdata);
4129
static void camerasolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
4131
Scene *scene = cob->scene;
4132
bCameraSolverConstraint *data = con->data;
4133
MovieClip *clip = data->clip;
4135
if (data->flag & CAMERASOLVER_ACTIVECLIP)
4139
float mat[4][4], obmat[4][4];
4140
MovieTracking *tracking = &clip->tracking;
4141
MovieTrackingObject *object = BKE_tracking_get_camera_object(tracking);
4143
BKE_tracking_get_interpolated_camera(tracking, object, scene->r.cfra, mat);
4145
copy_m4_m4(obmat, cob->matrix);
4147
mult_m4_m4m4(cob->matrix, obmat, mat);
4151
static bConstraintTypeInfo CTI_CAMERASOLVER = {
4152
CONSTRAINT_TYPE_CAMERASOLVER, /* type */
4153
sizeof(bCameraSolverConstraint), /* size */
4154
"Camera Solver", /* name */
4155
"bCameraSolverConstraint", /* struct name */
4156
NULL, /* free data */
4157
NULL, /* relink data */
4158
camerasolver_id_looper, /* id looper */
4159
NULL, /* copy data */
4160
camerasolver_new_data, /* new data */
4161
NULL, /* get constraint targets */
4162
NULL, /* flush constraint targets */
4163
NULL, /* get target matrix */
4164
camerasolver_evaluate /* evaluate */
4167
/* ----------- Object Solver ------------- */
4169
static void objectsolver_new_data(void *cdata)
4171
bObjectSolverConstraint *data = (bObjectSolverConstraint *)cdata;
4174
data->flag |= OBJECTSOLVER_ACTIVECLIP;
4175
unit_m4(data->invmat);
4178
static void objectsolver_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
4180
bObjectSolverConstraint *data= con->data;
4182
func(con, (ID**)&data->clip, FALSE, userdata);
4183
func(con, (ID**)&data->camera, FALSE, userdata);
4186
static void objectsolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
4188
Scene *scene = cob->scene;
4189
bObjectSolverConstraint *data = con->data;
4190
MovieClip *clip = data->clip;
4191
Object *camob = data->camera ? data->camera : scene->camera;
4193
if (data->flag & OBJECTSOLVER_ACTIVECLIP)
4196
if (!camob || !clip)
4200
MovieTracking *tracking = &clip->tracking;
4201
MovieTrackingObject *object;
4203
object = BKE_tracking_named_object(tracking, data->object);
4206
float mat[4][4], obmat[4][4], imat[4][4], cammat[4][4], camimat[4][4], parmat[4][4];
4208
where_is_object_mat(scene, camob, cammat);
4210
BKE_tracking_get_interpolated_camera(tracking, object, scene->r.cfra, mat);
4212
invert_m4_m4(camimat, cammat);
4213
mult_m4_m4m4(parmat, cammat, data->invmat);
4215
copy_m4_m4(cammat, camob->obmat);
4216
copy_m4_m4(obmat, cob->matrix);
4218
invert_m4_m4(imat, mat);
4220
mul_serie_m4(cob->matrix, cammat, imat, camimat, parmat, obmat, NULL, NULL, NULL);
4225
static bConstraintTypeInfo CTI_OBJECTSOLVER = {
4226
CONSTRAINT_TYPE_OBJECTSOLVER, /* type */
4227
sizeof(bObjectSolverConstraint), /* size */
4228
"Object Solver", /* name */
4229
"bObjectSolverConstraint", /* struct name */
4230
NULL, /* free data */
4231
NULL, /* relink data */
4232
objectsolver_id_looper, /* id looper */
4233
NULL, /* copy data */
4234
objectsolver_new_data, /* new data */
4235
NULL, /* get constraint targets */
4236
NULL, /* flush constraint targets */
4237
NULL, /* get target matrix */
4238
objectsolver_evaluate /* evaluate */
3946
4241
/* ************************* Constraints Type-Info *************************** */
3947
4242
/* All of the constraints api functions use bConstraintTypeInfo structs to carry out
3948
4243
* and operations that involve constraint specific code.