[Bf-blender-cvs] [f2e88ba2edf] asset-greasepencil: GPencil: Rotate Asset
Antonio Vazquez
noreply at git.blender.org
Sun Jul 18 23:07:06 CEST 2021
Commit: f2e88ba2edfb0dcd2740ea697b56a72102da71e4
Author: Antonio Vazquez
Date: Sun Jul 18 23:06:51 2021 +0200
Branches: asset-greasepencil
https://developer.blender.org/rBf2e88ba2edfb0dcd2740ea697b56a72102da71e4
GPencil: Rotate Asset
===================================================================
M source/blender/editors/gpencil/gpencil_asset.c
===================================================================
diff --git a/source/blender/editors/gpencil/gpencil_asset.c b/source/blender/editors/gpencil/gpencil_asset.c
index 062cc18b5cc..da334b46576 100644
--- a/source/blender/editors/gpencil/gpencil_asset.c
+++ b/source/blender/editors/gpencil/gpencil_asset.c
@@ -121,6 +121,10 @@ typedef struct tGPDasset {
int manipulator_index;
/** Manipulator vector used to determine the effect. */
float manipulator_vector[3];
+ /** Normal vector for cage. */
+ float normal_vec[3];
+ /** Vector with the original orientation for rotation. */
+ float vinit_rotation[2];
/** Hash of new created layers. */
struct GHash *asset_layers;
@@ -543,6 +547,17 @@ static void gpencil_2d_cage_calc(tGPDasset *tgpa)
/* Rotation */
tgpa->manipulator[8][0] = tgpa->rect_cage.xmax + ROTATION_CONTROL_GAP;
tgpa->manipulator[8][1] = tgpa->rect_cage.ymax + ROTATION_CONTROL_GAP;
+
+ /* Normal vector. */
+ float co1[3], co2[3], co3[3], vec1[3], vec2[3];
+ gpencil_point_xy_to_3d(&tgpa->gsc, tgpa->scene, tgpa->manipulator[CAGE_CORNER_NE], co1);
+ gpencil_point_xy_to_3d(&tgpa->gsc, tgpa->scene, tgpa->manipulator[CAGE_CORNER_NW], co2);
+ gpencil_point_xy_to_3d(&tgpa->gsc, tgpa->scene, tgpa->manipulator[CAGE_CORNER_SW], co3);
+ sub_v3_v3v3(vec1, co2, co1);
+ sub_v3_v3v3(vec2, co3, co2);
+ /* Vector orthogonal to polygon plane. */
+ cross_v3_v3v3(tgpa->normal_vec, vec1, vec2);
+ normalize_v3(tgpa->normal_vec);
}
/* Helper: Detect mouse over cage areas. */
@@ -605,6 +620,52 @@ static void gpencil_2d_cage_area_detect(tGPDasset *tgpa, const int mouse[2])
WM_cursor_modal_set(tgpa->win, WM_CURSOR_DEFAULT);
}
+/* Helper: Get the rotation matrix for the angle using an arbitrary vector as axis. */
+static void gpencil_asset_rotation_matrix_get(float angle,
+ float axis[3],
+ float rotation_matrix[4][4])
+{
+ float u2 = axis[0] * axis[0];
+ float v2 = axis[1] * axis[1];
+ float w2 = axis[2] * axis[2];
+ const float length = (u2 + v2 + w2);
+ const float length_sqr = sqrt(length);
+ const float cos_value = cos(angle);
+ const float sin_value = sin(angle);
+
+ rotation_matrix[0][0] = (u2 + (v2 + w2) * cos_value) / length;
+ rotation_matrix[0][1] = (axis[0] * axis[1] * (1.0f - cos_value) -
+ axis[2] * length_sqr * sin_value) /
+ length;
+ rotation_matrix[0][2] = (axis[0] * axis[2] * (1.0f - cos_value) +
+ axis[1] * length_sqr * sin_value) /
+ length;
+ rotation_matrix[0][3] = 0.0;
+
+ rotation_matrix[1][0] = (axis[0] * axis[1] * (1.0f - cos_value) +
+ axis[2] * length_sqr * sin_value) /
+ length;
+ rotation_matrix[1][1] = (v2 + (u2 + w2) * cos_value) / length;
+ rotation_matrix[1][2] = (axis[1] * axis[2] * (1.0f - cos_value) -
+ axis[0] * length_sqr * sin_value) /
+ length;
+ rotation_matrix[1][3] = 0.0f;
+
+ rotation_matrix[2][0] = (axis[0] * axis[2] * (1.0f - cos_value) -
+ axis[1] * length_sqr * sin_value) /
+ length;
+ rotation_matrix[2][1] = (axis[1] * axis[2] * (1.0f - cos_value) +
+ axis[0] * length_sqr * sin_value) /
+ length;
+ rotation_matrix[2][2] = (w2 + (u2 + v2) * cos_value) / length;
+ rotation_matrix[2][3] = 0.0f;
+
+ rotation_matrix[3][0] = 0.0f;
+ rotation_matrix[3][1] = 0.0f;
+ rotation_matrix[3][2] = 0.0f;
+ rotation_matrix[3][3] = 1.0f;
+}
+
/* Helper: Transfrom the stroke with mouse movements. */
static void gpencil_asset_transform_strokes(tGPDasset *tgpa,
const int mouse[2],
@@ -648,6 +709,14 @@ static void gpencil_asset_transform_strokes(tGPDasset *tgpa,
}
}
+ /* Create rotation matrix. */
+ float rot_matrix[4][4];
+ float vr[2];
+ copy_v2fl_v2i(vr, mouse);
+ normalize_v2(vr);
+ float angle = angle_signed_v2v2(tgpa->vinit_rotation, vr);
+ gpencil_asset_rotation_matrix_get(angle, tgpa->normal_vec, rot_matrix);
+
GHashIterator gh_iter;
GHASH_ITER (gh_iter, tgpa->asset_strokes) {
bGPDstroke *gps = (bGPDstroke *)BLI_ghashIterator_getKey(&gh_iter);
@@ -660,6 +729,9 @@ static void gpencil_asset_transform_strokes(tGPDasset *tgpa,
break;
}
case GP_ASSET_TRANSFORM_ROT: {
+ sub_v3_v3(&pt->x, pivot);
+ mul_v3_m4v3(&pt->x, rot_matrix, &pt->x);
+ add_v3_v3(&pt->x, pivot);
break;
}
case GP_ASSET_TRANSFORM_SCALE: {
@@ -684,11 +756,17 @@ static void gpencil_asset_transform_strokes(tGPDasset *tgpa,
}
}
- /* Recalc stroke bounding box. */
- BKE_gpencil_stroke_boundingbox_calc(gps);
+ /* In scale mode recal geometry. */
+ if (tgpa->mode == GP_ASSET_TRANSFORM_SCALE) {
+ BKE_gpencil_stroke_geometry_update(tgpa->gpd, gps);
+ }
+ else {
+ /* Recalc stroke bounding box. */
+ BKE_gpencil_stroke_boundingbox_calc(gps);
+ }
}
- /* In ocation mode move the asset center. */
+ /* In location mode move the asset center. */
if (tgpa->mode == GP_ASSET_TRANSFORM_LOC) {
add_v3_v3(tgpa->asset_center, vec);
}
@@ -771,6 +849,9 @@ static void gpencil_asset_add_strokes(tGPDasset *tgpa)
}
gps_target->mat_nr = mat_index;
+
+ BKE_gpencil_stroke_geometry_update(gpd_target, gps_target);
+
/* Add the hash key with a reference to the frame. */
BLI_ghash_insert(tgpa->asset_strokes, gps_target, gpf_target);
}
@@ -834,16 +915,21 @@ static void gpencil_draw_cage(tGPDasset *tgpa)
float box_color[4];
UI_GetThemeColor4fv(TH_VERTEX_SELECT, box_color);
immUniformColor4fv(box_color);
- imm_draw_box_wire_2d(
- pos, tgpa->rect_cage.xmin, tgpa->rect_cage.ymin, tgpa->rect_cage.xmax, tgpa->rect_cage.ymax);
+
+ immBegin(GPU_PRIM_LINE_LOOP, 4);
+ immVertex2f(pos, tgpa->manipulator[CAGE_CORNER_NW][0], tgpa->manipulator[CAGE_CORNER_NW][1]);
+ immVertex2f(pos, tgpa->manipulator[CAGE_CORNER_NE][0], tgpa->manipulator[CAGE_CORNER_NE][1]);
+ immVertex2f(pos, tgpa->manipulator[CAGE_CORNER_SE][0], tgpa->manipulator[CAGE_CORNER_SE][1]);
+ immVertex2f(pos, tgpa->manipulator[CAGE_CORNER_SW][0], tgpa->manipulator[CAGE_CORNER_SW][1]);
+ immEnd();
/* Rotation box */
const float gap = 5.0f;
imm_draw_box_wire_2d(pos,
- tgpa->manipulator[8][0] - gap,
- tgpa->manipulator[8][1] - gap,
- tgpa->manipulator[8][0] + gap,
- tgpa->manipulator[8][1] + gap);
+ tgpa->manipulator[CAGE_CORNER_ROT][0] - gap,
+ tgpa->manipulator[CAGE_CORNER_ROT][1] - gap,
+ tgpa->manipulator[CAGE_CORNER_ROT][0] + gap,
+ tgpa->manipulator[CAGE_CORNER_ROT][1] + gap);
immUnbindProgram();
@@ -943,6 +1029,10 @@ static int gpencil_asset_import_modal(bContext *C, wmOperator *op, const wmEvent
sub_v3_v3v3(mouse3d, mouse3d, tgpa->asset_center);
tgpa->initial_dist = len_v3(mouse3d);
+ /* Initial orientation for rotation. */
+ copy_v2fl_v2i(tgpa->vinit_rotation, tgpa->mouse);
+ normalize_v2(tgpa->vinit_rotation);
+
tgpa->flag &= ~GP_ASSET_FLAG_IDLE;
tgpa->flag |= GP_ASSET_FLAG_RUNNING;
}
More information about the Bf-blender-cvs
mailing list