Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/transform/transform_mode_rotate.c
| Show First 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| float point[3]; | float point[3]; | ||||
| getSnapPoint(t, point); | getSnapPoint(t, point); | ||||
| float dist = RotationBetween(t, t->tsnap.snapTarget, point); | float dist = RotationBetween(t, t->tsnap.snapTarget, point); | ||||
| *value = dist; | *value = dist; | ||||
| } | } | ||||
| static void rotate_get_axis(TransInfo *t, float r_axis[3], bool *r_flip_angle) | |||||
| { | |||||
| *r_flip_angle = false; | |||||
| if ((t->con.mode & CON_APPLY) && t->con.applyRot) { | |||||
| t->con.applyRot(t, NULL, NULL, r_axis, NULL); | |||||
| } | |||||
| else { | |||||
| copy_v3_v3(r_axis, t->spacemtx[t->orient_axis]); | |||||
| if (!(t->flag & T_INPUT_IS_VALUES_FINAL) && (dot_v3v3(r_axis, t->viewinv[2]) > 0.0f)) { | |||||
| /* The input is obtained according to the position of the mouse. | |||||
| * Flip to better match the movement. */ | |||||
| *r_flip_angle = true; | |||||
| } | |||||
| } | |||||
| } | |||||
| static void rotate_update_baseboint_fn(TransInfo *t, | |||||
| const float new_base_point[3], | |||||
| float r_base_point_final[3]) | |||||
| { | |||||
| float mat[3][3]; | |||||
| float angle = -t->values_final[0]; | |||||
| { | |||||
| float axis_final[3]; | |||||
| bool dummy; | |||||
| rotate_get_axis(t, axis_final, &dummy); | |||||
| axis_angle_normalized_to_mat3(mat, axis_final, angle); | |||||
| } | |||||
| mul_v3_m3v3(r_base_point_final, mat, new_base_point); | |||||
| } | |||||
| static float large_rotation_limit(float angle) | static float large_rotation_limit(float angle) | ||||
| { | { | ||||
| /* Limit rotation to 1001 turns max | /* Limit rotation to 1001 turns max | ||||
| * (otherwise iterative handling of 'large' rotations would become too slow). */ | * (otherwise iterative handling of 'large' rotations would become too slow). */ | ||||
| const float angle_max = (float)(M_PI * 2000.0); | const float angle_max = (float)(M_PI * 2000.0); | ||||
| if (fabsf(angle) > angle_max) { | if (fabsf(angle) > angle_max) { | ||||
| const float angle_sign = angle < 0.0f ? -1.0f : 1.0f; | const float angle_sign = angle < 0.0f ? -1.0f : 1.0f; | ||||
| angle = angle_sign * (fmodf(fabsf(angle), (float)(M_PI * 2.0)) + angle_max); | angle = angle_sign * (fmodf(fabsf(angle), (float)(M_PI * 2.0)) + angle_max); | ||||
| ▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | static void applyRotationValue(TransInfo *t, | ||||
| } | } | ||||
| } | } | ||||
| static void applyRotation(TransInfo *t, const int UNUSED(mval[2])) | static void applyRotation(TransInfo *t, const int UNUSED(mval[2])) | ||||
| { | { | ||||
| char str[UI_MAX_DRAW_STR]; | char str[UI_MAX_DRAW_STR]; | ||||
| float axis_final[3]; | float axis_final[3]; | ||||
| float final = t->values[0]; | float final = t->values[0]; | ||||
| bool invert_angle; | |||||
| if ((t->con.mode & CON_APPLY) && t->con.applyRot) { | rotate_get_axis(t, axis_final, &invert_angle); | ||||
| t->con.applyRot(t, NULL, NULL, axis_final, NULL); | if (applyNumInput(&t->num, &final)) { | ||||
| /* We have to limit the amount of turns to a reasonable number here, | |||||
| * to avoid things getting *very* slow, see how applyRotationValue() handles those... */ | |||||
| final = large_rotation_limit(final); | |||||
| } | } | ||||
| else { | else { | ||||
| copy_v3_v3(axis_final, t->spacemtx[t->orient_axis]); | if (invert_angle) { | ||||
| if (!(t->flag & T_INPUT_IS_VALUES_FINAL) && (dot_v3v3(axis_final, t->viewinv[2]) > 0.0f)) { | |||||
| /* The input is obtained according to the position of the mouse. | /* The input is obtained according to the position of the mouse. | ||||
| * Flip to better match the movement. */ | * Flip to better match the movement. */ | ||||
| final *= -1; | final *= -1; | ||||
| } | } | ||||
| applySnapping(t, &final); | |||||
| if (!(activeSnap(t) && validSnap(t))) { | |||||
| transform_snap_increment(t, &final); | |||||
| } | } | ||||
| else if (invert_angle) { | |||||
| if (applyNumInput(&t->num, &final)) { | final *= -1; | ||||
| /* We have to limit the amount of turns to a reasonable number here, | |||||
| * to avoid things getting *very* slow, see how applyRotationValue() handles those... */ | |||||
| final = large_rotation_limit(final); | |||||
| } | } | ||||
| else { | |||||
| transform_snap_increment(t, &final); | |||||
| applySnapping(t, &final); | |||||
| } | } | ||||
| t->values_final[0] = final; | t->values_final[0] = final; | ||||
| headerRotation(t, str, final); | headerRotation(t, str, final); | ||||
| const bool is_large_rotation = hasNumInput(&t->num); | const bool is_large_rotation = hasNumInput(&t->num); | ||||
| applyRotationValue(t, final, axis_final, is_large_rotation); | applyRotationValue(t, final, axis_final, is_large_rotation); | ||||
| recalcData(t); | recalcData(t); | ||||
| ED_area_status_text(t->area, str); | ED_area_status_text(t->area, str); | ||||
| } | } | ||||
| void initRotation(TransInfo *t) | void initRotation(TransInfo *t) | ||||
| { | { | ||||
| t->mode = TFM_ROTATION; | t->mode = TFM_ROTATION; | ||||
| t->transform = applyRotation; | t->transform = applyRotation; | ||||
| t->tsnap.applySnap = ApplySnapRotation; | t->tsnap.applySnap = ApplySnapRotation; | ||||
| t->tsnap.updateBasePoint = rotate_update_baseboint_fn; | |||||
| t->tsnap.distance = RotationBetween; | t->tsnap.distance = RotationBetween; | ||||
| setInputPostFct(&t->mouse, postInputRotation); | setInputPostFct(&t->mouse, postInputRotation); | ||||
| initMouseInputMode(t, &t->mouse, INPUT_ANGLE); | initMouseInputMode(t, &t->mouse, INPUT_ANGLE); | ||||
| t->idx_max = 0; | t->idx_max = 0; | ||||
| t->num.idx_max = 0; | t->num.idx_max = 0; | ||||
| t->snap[0] = DEG2RAD(5.0); | t->snap[0] = DEG2RAD(5.0); | ||||
| Show All 12 Lines | |||||