Camera tracking: add camera to follow track and object solver constraint
Object used to be parented to active camera which isn't very convenient when working with witness cameras. Now parent camera can be specified in constraint (if it's not specified, active camera is used)
This commit is contained in:
@@ -776,6 +776,8 @@ class ConstraintButtonsPanel():
|
||||
layout.prop_search(con, "object", clip.tracking, "objects", icon='OBJECT_DATA')
|
||||
layout.prop_search(con, "track", clip.tracking, "tracks", icon='ANIMATION_DATA')
|
||||
|
||||
layout.prop(con, "camera")
|
||||
|
||||
layout.operator("clip.constraint_to_fcurve")
|
||||
|
||||
def CAMERA_SOLVER(self, context, layout, con):
|
||||
@@ -798,6 +800,8 @@ class ConstraintButtonsPanel():
|
||||
if clip:
|
||||
layout.prop_search(con, "object", clip.tracking, "objects", icon='OBJECT_DATA')
|
||||
|
||||
layout.prop(con, "camera")
|
||||
|
||||
row = layout.row()
|
||||
row.operator("constraint.objectsolver_set_inverse")
|
||||
row.operator("constraint.objectsolver_clear_inverse")
|
||||
|
||||
@@ -3937,6 +3937,7 @@ static void followtrack_id_looper (bConstraint *con, ConstraintIDFunc func, void
|
||||
bFollowTrackConstraint *data= con->data;
|
||||
|
||||
func(con, (ID**)&data->clip, userdata);
|
||||
func(con, (ID**)&data->camera, userdata);
|
||||
}
|
||||
|
||||
static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
|
||||
@@ -3947,11 +3948,12 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase
|
||||
MovieTracking *tracking;
|
||||
MovieTrackingTrack *track;
|
||||
MovieTrackingObject *tracking_object;
|
||||
Object *camob= data->camera ? data->camera : scene->camera;
|
||||
|
||||
if (data->flag & FOLLOWTRACK_ACTIVECLIP)
|
||||
clip= scene->clip;
|
||||
|
||||
if (!clip || !data->track[0])
|
||||
if (!clip || !data->track[0] || !camob)
|
||||
return;
|
||||
|
||||
tracking= &clip->tracking;
|
||||
@@ -3975,12 +3977,8 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase
|
||||
float pos[3], mat[4][4];
|
||||
|
||||
if((tracking_object->flag&TRACKING_OBJECT_CAMERA)==0) {
|
||||
Object *camob= scene->camera;
|
||||
float obmat[4][4], imat[4][4];
|
||||
|
||||
if(!camob)
|
||||
return;
|
||||
|
||||
copy_m4_m4(mat, camob->obmat);
|
||||
|
||||
BKE_tracking_get_interpolated_camera(tracking, tracking_object, scene->r.cfra, obmat);
|
||||
@@ -4000,77 +3998,73 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase
|
||||
}
|
||||
}
|
||||
else {
|
||||
Object *camob= scene->camera;
|
||||
MovieClipUser user;
|
||||
MovieTrackingMarker *marker;
|
||||
float vec[3], disp[3], axis[3], mat[4][4];
|
||||
float aspect= (scene->r.xsch*scene->r.xasp) / (scene->r.ysch*scene->r.yasp);
|
||||
float len, d;
|
||||
|
||||
if (camob) {
|
||||
MovieClipUser user;
|
||||
MovieTrackingMarker *marker;
|
||||
float vec[3], disp[3], axis[3], mat[4][4];
|
||||
float aspect= (scene->r.xsch*scene->r.xasp) / (scene->r.ysch*scene->r.yasp);
|
||||
float len, d;
|
||||
where_is_object_mat(scene, camob, mat);
|
||||
|
||||
where_is_object_mat(scene, camob, mat);
|
||||
/* camera axis */
|
||||
vec[0]= 0.0f;
|
||||
vec[1]= 0.0f;
|
||||
vec[2]= 1.0f;
|
||||
mul_v3_m4v3(axis, mat, vec);
|
||||
|
||||
/* camera axis */
|
||||
vec[0]= 0.0f;
|
||||
vec[1]= 0.0f;
|
||||
vec[2]= 1.0f;
|
||||
mul_v3_m4v3(axis, mat, vec);
|
||||
/* distance to projection plane */
|
||||
copy_v3_v3(vec, cob->matrix[3]);
|
||||
sub_v3_v3(vec, mat[3]);
|
||||
project_v3_v3v3(disp, vec, axis);
|
||||
|
||||
/* distance to projection plane */
|
||||
copy_v3_v3(vec, cob->matrix[3]);
|
||||
sub_v3_v3(vec, mat[3]);
|
||||
project_v3_v3v3(disp, vec, axis);
|
||||
len= len_v3(disp);
|
||||
|
||||
len= len_v3(disp);
|
||||
if (len > FLT_EPSILON) {
|
||||
CameraParams params;
|
||||
float pos[2], rmat[4][4];
|
||||
|
||||
if (len > FLT_EPSILON) {
|
||||
CameraParams params;
|
||||
float pos[2], rmat[4][4];
|
||||
user.framenr= scene->r.cfra;
|
||||
marker= BKE_tracking_get_marker(track, user.framenr);
|
||||
|
||||
user.framenr= scene->r.cfra;
|
||||
marker= BKE_tracking_get_marker(track, user.framenr);
|
||||
add_v2_v2v2(pos, marker->pos, track->offset);
|
||||
|
||||
add_v2_v2v2(pos, marker->pos, track->offset);
|
||||
camera_params_init(¶ms);
|
||||
camera_params_from_object(¶ms, camob);
|
||||
|
||||
camera_params_init(¶ms);
|
||||
camera_params_from_object(¶ms, camob);
|
||||
if (params.is_ortho) {
|
||||
vec[0]= params.ortho_scale * (pos[0]-0.5f+params.shiftx);
|
||||
vec[1]= params.ortho_scale * (pos[1]-0.5f+params.shifty);
|
||||
vec[2]= -len;
|
||||
|
||||
if (params.is_ortho) {
|
||||
vec[0]= params.ortho_scale * (pos[0]-0.5f+params.shiftx);
|
||||
vec[1]= params.ortho_scale * (pos[1]-0.5f+params.shifty);
|
||||
vec[2]= -len;
|
||||
if (aspect > 1.0f) vec[1] /= aspect;
|
||||
else vec[0] *= aspect;
|
||||
|
||||
if (aspect > 1.0f) vec[1] /= aspect;
|
||||
else vec[0] *= aspect;
|
||||
mul_v3_m4v3(disp, camob->obmat, vec);
|
||||
|
||||
mul_v3_m4v3(disp, camob->obmat, vec);
|
||||
copy_m4_m4(rmat, camob->obmat);
|
||||
zero_v3(rmat[3]);
|
||||
mul_m4_m4m4(cob->matrix, rmat, cob->matrix);
|
||||
|
||||
copy_m4_m4(rmat, camob->obmat);
|
||||
zero_v3(rmat[3]);
|
||||
mul_m4_m4m4(cob->matrix, rmat, cob->matrix);
|
||||
copy_v3_v3(cob->matrix[3], disp);
|
||||
}
|
||||
else {
|
||||
d= (len*params.sensor_x) / (2.0f*params.lens);
|
||||
|
||||
copy_v3_v3(cob->matrix[3], disp);
|
||||
}
|
||||
else {
|
||||
d= (len*params.sensor_x) / (2.0f*params.lens);
|
||||
vec[0]= d*(2.0f*(pos[0]+params.shiftx)-1.0f);
|
||||
vec[1]= d*(2.0f*(pos[1]+params.shifty)-1.0f);
|
||||
vec[2]= -len;
|
||||
|
||||
vec[0]= d*(2.0f*(pos[0]+params.shiftx)-1.0f);
|
||||
vec[1]= d*(2.0f*(pos[1]+params.shifty)-1.0f);
|
||||
vec[2]= -len;
|
||||
if (aspect > 1.0f) vec[1] /= aspect;
|
||||
else vec[0] *= aspect;
|
||||
|
||||
if (aspect > 1.0f) vec[1] /= aspect;
|
||||
else vec[0] *= aspect;
|
||||
mul_v3_m4v3(disp, camob->obmat, vec);
|
||||
|
||||
mul_v3_m4v3(disp, camob->obmat, vec);
|
||||
/* apply camera rotation so Z-axis would be co-linear */
|
||||
copy_m4_m4(rmat, camob->obmat);
|
||||
zero_v3(rmat[3]);
|
||||
mul_m4_m4m4(cob->matrix, rmat, cob->matrix);
|
||||
|
||||
/* apply camera rotation so Z-axis would be co-linear */
|
||||
copy_m4_m4(rmat, camob->obmat);
|
||||
zero_v3(rmat[3]);
|
||||
mul_m4_m4m4(cob->matrix, rmat, cob->matrix);
|
||||
|
||||
copy_v3_v3(cob->matrix[3], disp);
|
||||
}
|
||||
copy_v3_v3(cob->matrix[3], disp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4162,6 +4156,7 @@ static void objectsolver_id_looper (bConstraint *con, ConstraintIDFunc func, voi
|
||||
bObjectSolverConstraint *data= con->data;
|
||||
|
||||
func(con, (ID**)&data->clip, userdata);
|
||||
func(con, (ID**)&data->camera, userdata);
|
||||
}
|
||||
|
||||
static void objectsolver_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
|
||||
@@ -4169,11 +4164,12 @@ static void objectsolver_evaluate (bConstraint *con, bConstraintOb *cob, ListBas
|
||||
Scene *scene= cob->scene;
|
||||
bObjectSolverConstraint *data= con->data;
|
||||
MovieClip *clip= data->clip;
|
||||
Object *camob= data->camera ? data->camera : scene->camera;
|
||||
|
||||
if (data->flag & OBJECTSOLVER_ACTIVECLIP)
|
||||
clip= scene->clip;
|
||||
|
||||
if(!scene->camera)
|
||||
if(!camob || !clip)
|
||||
return;
|
||||
|
||||
if (clip) {
|
||||
@@ -4185,14 +4181,14 @@ static void objectsolver_evaluate (bConstraint *con, bConstraintOb *cob, ListBas
|
||||
if(object) {
|
||||
float mat[4][4], obmat[4][4], imat[4][4], cammat[4][4], camimat[4][4], parmat[4][4];
|
||||
|
||||
where_is_object_mat(scene, scene->camera, cammat);
|
||||
where_is_object_mat(scene, camob, cammat);
|
||||
|
||||
BKE_tracking_get_interpolated_camera(tracking, object, scene->r.cfra, mat);
|
||||
|
||||
invert_m4_m4(camimat, cammat);
|
||||
mul_m4_m4m4(parmat, data->invmat, cammat);
|
||||
|
||||
copy_m4_m4(cammat, scene->camera->obmat);
|
||||
copy_m4_m4(cammat, camob->obmat);
|
||||
copy_m4_m4(obmat, cob->matrix);
|
||||
|
||||
invert_m4_m4(imat, mat);
|
||||
|
||||
@@ -6818,14 +6818,28 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
|
||||
ListBase targets = {NULL, NULL};
|
||||
bConstraintTarget *ct;
|
||||
|
||||
if(cti->type==CONSTRAINT_TYPE_OBJECTSOLVER) {
|
||||
/* special case for object solver constraint because it doesn't fill
|
||||
constraint targets properly (design limitation -- scene is needed for
|
||||
it's target but it can't be accessed from get_targets callvack) */
|
||||
if(scene->camera) {
|
||||
if(ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_OBJECTSOLVER)) {
|
||||
/* special case for object solver and follow track constraints because they don't fill
|
||||
constraint targets properly (design limitation -- scene is needed for their target
|
||||
but it can't be accessed from get_targets callvack) */
|
||||
|
||||
Object *camob= NULL;
|
||||
|
||||
if(cti->type==CONSTRAINT_TYPE_FOLLOWTRACK) {
|
||||
bFollowTrackConstraint *data= (bFollowTrackConstraint *)curcon->data;
|
||||
|
||||
camob= data->camera ? data->camera : scene->camera;
|
||||
}
|
||||
else if(cti->type==CONSTRAINT_TYPE_OBJECTSOLVER) {
|
||||
bObjectSolverConstraint *data= (bObjectSolverConstraint *)curcon->data;
|
||||
|
||||
camob= data->camera ? data->camera : scene->camera;
|
||||
}
|
||||
|
||||
if(camob) {
|
||||
setlinestyle(3);
|
||||
glBegin(GL_LINES);
|
||||
glVertex3fv(scene->camera->obmat[3]);
|
||||
glVertex3fv(camob->obmat[3]);
|
||||
glVertex3fv(ob->obmat[3]);
|
||||
glEnd();
|
||||
setlinestyle(0);
|
||||
|
||||
@@ -413,6 +413,7 @@ typedef struct bFollowTrackConstraint {
|
||||
char track[24];
|
||||
int flag, pad;
|
||||
char object[24];
|
||||
struct Object *camera;
|
||||
} bFollowTrackConstraint;
|
||||
|
||||
/* Camera Solver constraints */
|
||||
@@ -427,6 +428,7 @@ typedef struct bObjectSolverConstraint {
|
||||
int flag, pad;
|
||||
char object[24];
|
||||
float invmat[4][4]; /* parent-inverse matrix to use */
|
||||
struct Object *camera;
|
||||
} bObjectSolverConstraint;
|
||||
|
||||
/* ------------------------------------------ */
|
||||
|
||||
@@ -330,6 +330,49 @@ static void rna_SplineIKConstraint_joint_bindings_set(PointerRNA *ptr, const flo
|
||||
memcpy(ikData->points, values, ikData->numpoints * sizeof(float));
|
||||
}
|
||||
|
||||
static int rna_Constraint_cameraObject_poll(PointerRNA *ptr, PointerRNA value)
|
||||
{
|
||||
Object *ob= (Object*)value.data;
|
||||
|
||||
if (ob) {
|
||||
if (ob->type == OB_CAMERA && ob != (Object*)ptr->id.data) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rna_Constraint_followTrack_camera_set(PointerRNA *ptr, PointerRNA value)
|
||||
{
|
||||
bConstraint *con= (bConstraint*)ptr->data;
|
||||
bFollowTrackConstraint *data= (bFollowTrackConstraint*)con->data;
|
||||
Object *ob= (Object*)value.data;
|
||||
|
||||
if (ob) {
|
||||
if (ob->type == OB_CAMERA && ob != (Object*)ptr->id.data) {
|
||||
data->camera= ob;
|
||||
}
|
||||
} else {
|
||||
data->camera= NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void rna_Constraint_objectSolver_camera_set(PointerRNA *ptr, PointerRNA value)
|
||||
{
|
||||
bConstraint *con= (bConstraint*)ptr->data;
|
||||
bObjectSolverConstraint *data= (bObjectSolverConstraint*)con->data;
|
||||
Object *ob= (Object*)value.data;
|
||||
|
||||
if (ob) {
|
||||
if (ob->type == OB_CAMERA && ob != (Object*)ptr->id.data) {
|
||||
data->camera= ob;
|
||||
}
|
||||
} else {
|
||||
data->camera= NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
EnumPropertyItem constraint_distance_items[] = {
|
||||
@@ -2073,8 +2116,16 @@ static void rna_def_constraint_follow_track(BlenderRNA *brna)
|
||||
/* object */
|
||||
prop= RNA_def_property(srna, "object", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, NULL, "object");
|
||||
RNA_def_property_ui_text(prop, "Object", "Movie tracking object to follow");
|
||||
RNA_def_property_ui_text(prop, "Object", "Movie tracking object to follow (if empty, camera object is used)");
|
||||
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
|
||||
|
||||
/* camera */
|
||||
prop= RNA_def_property(srna, "camera", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_pointer_sdna(prop, NULL, "camera");
|
||||
RNA_def_property_ui_text(prop, "Camera", "Camera to which motion is parented (if empty active scene camera is used)");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
|
||||
RNA_def_property_pointer_funcs(prop, NULL, "rna_Constraint_followTrack_camera_set", NULL, "rna_Constraint_cameraObject_poll");
|
||||
}
|
||||
|
||||
static void rna_def_constraint_camera_solver(BlenderRNA *brna)
|
||||
@@ -2127,6 +2178,14 @@ static void rna_def_constraint_object_solver(BlenderRNA *brna)
|
||||
RNA_def_property_string_sdna(prop, NULL, "object");
|
||||
RNA_def_property_ui_text(prop, "Object", "Movie tracking object to follow");
|
||||
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
|
||||
|
||||
/* camera */
|
||||
prop= RNA_def_property(srna, "camera", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_pointer_sdna(prop, NULL, "camera");
|
||||
RNA_def_property_ui_text(prop, "Camera", "Camera to which motion is parented (if empty active scene camera is used)");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
|
||||
RNA_def_property_pointer_funcs(prop, NULL, "rna_Constraint_objectSolver_camera_set", NULL, "rna_Constraint_cameraObject_poll");
|
||||
}
|
||||
|
||||
/* base struct for constraints */
|
||||
|
||||
Reference in New Issue
Block a user