/* returns standard diameter */ static float new_primitive_matrix(bContext *C, float *loc, float *rot, float primmat[][4]) { Object *obedit = CTX_data_edit_object(C); View3D *v3d = CTX_wm_view3d(C); float mat[3][3], rmat[3][3], cmat[3][3], imat[3][3]; unit_m4(primmat); eul_to_mat3(rmat, rot); invert_m3(rmat); /* inverse transform for initial rotation and object */ copy_m3_m4(mat, obedit->obmat); mul_m3_m3m3(cmat, rmat, mat); invert_m3_m3(imat, cmat); copy_m4_m3(primmat, imat); /* center */ copy_v3_v3(primmat[3], loc); sub_v3_v3(primmat[3], obedit->obmat[3]); invert_m3_m3(imat, mat); mul_m3_v3(imat, primmat[3]); return v3d ? v3d->grid : 1.0f; }
static int armature_calc_roll_exec(bContext *C, wmOperator *op) { Object *ob = CTX_data_edit_object(C); const short type = RNA_enum_get(op->ptr, "type"); const short axis_only = RNA_boolean_get(op->ptr, "axis_only"); const short axis_flip = RNA_boolean_get(op->ptr, "axis_flip"); float imat[3][3]; bArmature *arm = ob->data; EditBone *ebone; copy_m3_m4(imat, ob->obmat); invert_m3(imat); if (type == CALC_ROLL_CURSOR) { /* Cursor */ Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); /* can be NULL */ float cursor_local[3]; const float *cursor = give_cursor(scene, v3d); copy_v3_v3(cursor_local, cursor); mul_m3_v3(imat, cursor_local); /* cursor */ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { if (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) { float cursor_rel[3]; sub_v3_v3v3(cursor_rel, cursor_local, ebone->head); if (axis_flip) negate_v3(cursor_rel); ebone->roll = ED_rollBoneToVector(ebone, cursor_rel, axis_only); } } } else { float vec[3] = {0.0f, 0.0f, 0.0f}; if (type == CALC_ROLL_VIEW) { /* View */ RegionView3D *rv3d = CTX_wm_region_view3d(C); if (rv3d == NULL) { BKE_report(op->reports, RPT_ERROR, "No region view3d available"); return OPERATOR_CANCELLED; } copy_v3_v3(vec, rv3d->viewinv[2]); mul_m3_v3(imat, vec); } else if (type == CALC_ROLL_ACTIVE) { float mat[3][3], nor[3]; ebone = (EditBone *)arm->act_edbone; if (ebone == NULL) { BKE_report(op->reports, RPT_ERROR, "No active bone set"); return OPERATOR_CANCELLED; } sub_v3_v3v3(nor, ebone->tail, ebone->head); vec_roll_to_mat3(nor, ebone->roll, mat); copy_v3_v3(vec, mat[2]); } else { /* Axis */ assert(type >= 0 && type <= 5); if (type < 3) vec[type] = 1.0f; else vec[type - 2] = -1.0f; mul_m3_v3(imat, vec); } if (axis_flip) negate_v3(vec); for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { if (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) { /* roll func is a callback which assumes that all is well */ ebone->roll = ED_rollBoneToVector(ebone, vec, axis_only); } } } if (arm->flag & ARM_MIRROR_EDIT) { for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { if ((EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) == 0) { EditBone *ebone_mirr = ED_armature_bone_get_mirrored(arm->edbo, ebone); if (ebone_mirr && (EBONE_VISIBLE(arm, ebone_mirr) && EBONE_EDITABLE(ebone_mirr))) { ebone->roll = -ebone_mirr->roll; } } } } /* note, notifier might evolve */ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob); return OPERATOR_FINISHED; }
static int armature_calc_roll_exec(bContext *C, wmOperator *op) { Object *ob = CTX_data_edit_object(C); eCalcRollTypes type = RNA_enum_get(op->ptr, "type"); const bool axis_only = RNA_boolean_get(op->ptr, "axis_only"); /* axis_flip when matching the active bone never makes sense */ bool axis_flip = ((type >= CALC_ROLL_ACTIVE) ? RNA_boolean_get(op->ptr, "axis_flip") : (type >= CALC_ROLL_TAN_NEG_X) ? true : false); float imat[3][3]; bArmature *arm = ob->data; EditBone *ebone; if ((type >= CALC_ROLL_NEG_X) && (type <= CALC_ROLL_TAN_NEG_Z)) { type -= (CALC_ROLL_ACTIVE - CALC_ROLL_NEG_X); axis_flip = true; } copy_m3_m4(imat, ob->obmat); invert_m3(imat); if (type == CALC_ROLL_CURSOR) { /* Cursor */ Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); /* can be NULL */ float cursor_local[3]; const float *cursor = ED_view3d_cursor3d_get(scene, v3d); invert_m4_m4(ob->imat, ob->obmat); copy_v3_v3(cursor_local, cursor); mul_m4_v3(ob->imat, cursor_local); /* cursor */ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { if (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) { float cursor_rel[3]; sub_v3_v3v3(cursor_rel, cursor_local, ebone->head); if (axis_flip) negate_v3(cursor_rel); if (normalize_v3(cursor_rel) != 0.0f) { ebone->roll = ED_armature_ebone_roll_to_vector(ebone, cursor_rel, axis_only); } } } } else if (ELEM(type, CALC_ROLL_TAN_POS_X, CALC_ROLL_TAN_POS_Z)) { for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { if (ebone->parent) { bool is_edit = (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)); bool is_edit_parent = (EBONE_VISIBLE(arm, ebone->parent) && EBONE_EDITABLE(ebone->parent)); if (is_edit || is_edit_parent) { EditBone *ebone_other = ebone->parent; float dir_a[3]; float dir_b[3]; float vec[3]; bool is_vec_zero; sub_v3_v3v3(dir_a, ebone->tail, ebone->head); normalize_v3(dir_a); /* find the first bone in the chane with a different direction */ do { sub_v3_v3v3(dir_b, ebone_other->head, ebone_other->tail); normalize_v3(dir_b); if (type == CALC_ROLL_TAN_POS_Z) { cross_v3_v3v3(vec, dir_a, dir_b); } else { add_v3_v3v3(vec, dir_a, dir_b); } } while ((is_vec_zero = (normalize_v3(vec) < 0.00001f)) && (ebone_other = ebone_other->parent)); if (!is_vec_zero) { if (axis_flip) negate_v3(vec); if (is_edit) { ebone->roll = ED_armature_ebone_roll_to_vector(ebone, vec, axis_only); } /* parentless bones use cross product with child */ if (is_edit_parent) { if (ebone->parent->parent == NULL) { ebone->parent->roll = ED_armature_ebone_roll_to_vector(ebone->parent, vec, axis_only); } } } } } } } else { float vec[3] = {0.0f, 0.0f, 0.0f}; if (type == CALC_ROLL_VIEW) { /* View */ RegionView3D *rv3d = CTX_wm_region_view3d(C); if (rv3d == NULL) { BKE_report(op->reports, RPT_ERROR, "No region view3d available"); return OPERATOR_CANCELLED; } copy_v3_v3(vec, rv3d->viewinv[2]); mul_m3_v3(imat, vec); } else if (type == CALC_ROLL_ACTIVE) { float mat[3][3]; ebone = (EditBone *)arm->act_edbone; if (ebone == NULL) { BKE_report(op->reports, RPT_ERROR, "No active bone set"); return OPERATOR_CANCELLED; } ED_armature_ebone_to_mat3(ebone, mat); copy_v3_v3(vec, mat[2]); } else { /* Axis */ assert(type <= 5); if (type < 3) vec[type] = 1.0f; else vec[type - 2] = -1.0f; mul_m3_v3(imat, vec); normalize_v3(vec); } if (axis_flip) negate_v3(vec); for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { if (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) { /* roll func is a callback which assumes that all is well */ ebone->roll = ED_armature_ebone_roll_to_vector(ebone, vec, axis_only); } } } if (arm->flag & ARM_MIRROR_EDIT) { for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { if ((EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) == 0) { EditBone *ebone_mirr = ED_armature_ebone_get_mirrored(arm->edbo, ebone); if (ebone_mirr && (EBONE_VISIBLE(arm, ebone_mirr) && EBONE_EDITABLE(ebone_mirr))) { ebone->roll = -ebone_mirr->roll; } } } } /* note, notifier might evolve */ WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob); return OPERATOR_FINISHED; }
static void set_axis(Scene *scene, Object *ob, MovieClip *clip, MovieTrackingObject *tracking_object, MovieTrackingTrack *track, char axis) { Object *camera = get_camera_with_movieclip(scene, clip); const bool is_camera = (tracking_object->flag & TRACKING_OBJECT_CAMERA) != 0; bool flip = false; float mat[4][4], vec[3], obmat[4][4], dvec[3]; BKE_object_to_mat4(ob, obmat); BKE_tracking_get_camera_object_matrix(scene, camera, mat); mul_v3_m4v3(vec, mat, track->bundle_pos); copy_v3_v3(dvec, vec); if (!is_camera) { float imat[4][4]; object_solver_inverted_matrix(scene, ob, imat); mul_v3_m4v3(vec, imat, vec); invert_m4_m4(imat, obmat); mul_v3_m4v3(dvec, imat, vec); sub_v3_v3(vec, obmat[3]); } if (len_squared_v2(vec) < (1e-3f * 1e-3f)) { return; } unit_m4(mat); if (axis == 'X') { if (fabsf(dvec[1]) < 1e-3f) { flip = true; mat[0][0] = -1.0f; mat[0][1] = 0.0f; mat[0][2] = 0.0f; mat[1][0] = 0.0f; mat[1][1] = -1.0f; mat[1][2] = 0.0f; mat[2][0] = 0.0f; mat[2][1] = 0.0f; mat[2][2] = 1.0f; } else { copy_v3_v3(mat[0], vec); if (is_camera || fabsf(vec[2]) < 1e-3f) { mat[0][2] = 0.0f; mat[2][0] = 0.0f; mat[2][1] = 0.0f; mat[2][2] = 1.0f; cross_v3_v3v3(mat[1], mat[2], mat[0]); } else { vec[2] = 0.0f; cross_v3_v3v3(mat[1], mat[0], vec); cross_v3_v3v3(mat[2], mat[0], mat[1]); } } } else { if (fabsf(dvec[0]) < 1e-3f) { flip = true; mat[0][0] = -1.0f; mat[0][1] = 0.0f; mat[0][2] = 0.0f; mat[1][0] = 0.0f; mat[1][1] = -1.0f; mat[1][2] = 0.0f; mat[2][0] = 0.0f; mat[2][1] = 0.0f; mat[2][2] = 1.0f; } else { copy_v3_v3(mat[1], vec); if (is_camera || fabsf(vec[2]) < 1e-3f) { mat[1][2] = 0.0f; mat[2][0] = 0.0f; mat[2][1] = 0.0f; mat[2][2] = 1.0f; cross_v3_v3v3(mat[0], mat[1], mat[2]); } else { vec[2] = 0.0f; cross_v3_v3v3(mat[0], vec, mat[1]); cross_v3_v3v3(mat[2], mat[0], mat[1]); } } } normalize_v3(mat[0]); normalize_v3(mat[1]); normalize_v3(mat[2]); if (is_camera) { invert_m4(mat); mul_m4_m4m4(mat, mat, obmat); } else { if (!flip) { float lmat[4][4], ilmat[4][4], rmat[3][3]; BKE_object_rot_to_mat3(ob, rmat, true); invert_m3(rmat); mul_m4_m4m3(mat, mat, rmat); unit_m4(lmat); copy_v3_v3(lmat[3], obmat[3]); invert_m4_m4(ilmat, lmat); mul_m4_series(mat, lmat, mat, ilmat, obmat); } else { mul_m4_m4m4(mat, obmat, mat); } } BKE_object_apply_mat4(ob, mat, 0, 0); }
static void setup_vertex_point( Mask *mask, MaskSpline *spline, MaskSplinePoint *new_point, const float point_co[2], const float u, const float ctime, const MaskSplinePoint *reference_point, const bool reference_adjacent) { const MaskSplinePoint *reference_parent_point = NULL; BezTriple *bezt; float co[3]; copy_v2_v2(co, point_co); co[2] = 0.0f; /* point coordinate */ bezt = &new_point->bezt; bezt->h1 = bezt->h2 = HD_ALIGN; if (reference_point) { if (reference_point->bezt.h1 == HD_VECT && reference_point->bezt.h2 == HD_VECT) { /* If the reference point is sharp try using some smooth point as reference * for handles. */ int point_index = reference_point - spline->points; int delta = new_point == spline->points ? 1 : -1; int i = 0; for (i = 0; i < spline->tot_point - 1; ++i) { MaskSplinePoint *current_point; point_index += delta; if (point_index == -1 || point_index >= spline->tot_point) { if (spline->flag & MASK_SPLINE_CYCLIC) { if (point_index == -1) { point_index = spline->tot_point - 1; } else if (point_index >= spline->tot_point) { point_index = 0; } } else { break; } } current_point = &spline->points[point_index]; if (current_point->bezt.h1 != HD_VECT || current_point->bezt.h2 != HD_VECT) { bezt->h1 = bezt->h2 = MAX2(current_point->bezt.h2, current_point->bezt.h1); break; } } } else { bezt->h1 = bezt->h2 = MAX2(reference_point->bezt.h2, reference_point->bezt.h1); } reference_parent_point = reference_point; } else if (reference_adjacent) { if (spline->tot_point != 1) { MaskSplinePoint *prev_point, *next_point, *close_point; const int index = (int)(new_point - spline->points); if (spline->flag & MASK_SPLINE_CYCLIC) { prev_point = &spline->points[mod_i(index - 1, spline->tot_point)]; next_point = &spline->points[mod_i(index + 1, spline->tot_point)]; } else { prev_point = (index != 0) ? &spline->points[index - 1] : NULL; next_point = (index != spline->tot_point - 1) ? &spline->points[index + 1] : NULL; } if (prev_point && next_point) { close_point = (len_squared_v2v2(new_point->bezt.vec[1], prev_point->bezt.vec[1]) < len_squared_v2v2(new_point->bezt.vec[1], next_point->bezt.vec[1])) ? prev_point : next_point; } else { close_point = prev_point ? prev_point : next_point; } /* handle type */ char handle_type = 0; if (prev_point) { handle_type = prev_point->bezt.h2; } if (next_point) { handle_type = MAX2(next_point->bezt.h2, handle_type); } bezt->h1 = bezt->h2 = handle_type; /* parent */ reference_parent_point = close_point; /* note, we may want to copy other attributes later, radius? pressure? color? */ } } copy_v3_v3(bezt->vec[0], co); copy_v3_v3(bezt->vec[1], co); copy_v3_v3(bezt->vec[2], co); if (reference_parent_point) { new_point->parent = reference_parent_point->parent; if (new_point->parent.id) { float parent_matrix[3][3]; BKE_mask_point_parent_matrix_get(new_point, ctime, parent_matrix); invert_m3(parent_matrix); mul_m3_v2(parent_matrix, new_point->bezt.vec[1]); } } else { BKE_mask_parent_init(&new_point->parent); } if (spline->tot_point != 1) { BKE_mask_calc_handle_adjacent_interp(spline, new_point, u); } /* select new point */ MASKPOINT_SEL_ALL(new_point); ED_mask_select_flush_all(mask); }