Remove math for 2D affine transform

Commit e1665c3d31 added math to do 2D affine transformations with 3x3
matrices, but these matrices are also used for 3D transformations.

Remove added functions and use 4x4 matrices for 2D transformation.

Reviewed By: campbellbarton

Differential Revision: https://developer.blender.org/D12510
This commit is contained in:
Richard Antalik 2021-10-15 23:02:08 +02:00
parent 81514b0e91
commit e11b33fec3
Notes: blender-bot 2023-10-04 09:42:55 +02:00
Referenced by issue #95183, Regression: 2D transform gizmo broken/unreliable wrong axis
9 changed files with 70 additions and 120 deletions

View File

@ -326,13 +326,9 @@ void mat4_to_size(float size[3], const float M[4][4]);
void mat4_to_size_fix_shear(float size[3], const float M[4][4]);
void translate_m3(float mat[3][3], float tx, float ty);
void translate_m4(float mat[4][4], float tx, float ty, float tz);
void rotate_m3(float mat[3][3], const float angle);
void rotate_m4(float mat[4][4], const char axis, const float angle);
void rescale_m3(float mat[3][3], const float scale[2]);
void rescale_m4(float mat[4][4], const float scale[3]);
void transform_pivot_set_m3(float mat[3][3], const float pivot[2]);
void transform_pivot_set_m4(float mat[4][4], const float pivot[3]);
void mat4_to_rot(float rot[3][3], const float wmat[4][4]);
@ -343,10 +339,6 @@ void mat4_decompose(float loc[3], float quat[4], float size[3], const float wmat
void mat3_polar_decompose(const float mat3[3][3], float r_U[3][3], float r_P[3][3]);
void loc_rot_size_to_mat3(float R[3][3],
const float loc[2],
const float angle,
const float size[2]);
void loc_rot_size_to_mat4(float R[4][4],
const float loc[3],
const float rot[3][3],

View File

@ -2338,12 +2338,6 @@ void scale_m4_fl(float R[4][4], float scale)
R[3][0] = R[3][1] = R[3][2] = 0.0;
}
void translate_m3(float mat[3][3], float tx, float ty)
{
mat[2][0] += (tx * mat[0][0] + ty * mat[1][0]);
mat[2][1] += (tx * mat[0][1] + ty * mat[1][1]);
}
void translate_m4(float mat[4][4], float Tx, float Ty, float Tz)
{
mat[3][0] += (Tx * mat[0][0] + Ty * mat[1][0] + Tz * mat[2][0]);
@ -2351,18 +2345,6 @@ void translate_m4(float mat[4][4], float Tx, float Ty, float Tz)
mat[3][2] += (Tx * mat[0][2] + Ty * mat[1][2] + Tz * mat[2][2]);
}
void rotate_m3(float mat[3][3], const float angle)
{
const float angle_cos = cosf(angle);
const float angle_sin = sinf(angle);
for (int col = 0; col < 3; col++) {
float temp = angle_cos * mat[0][col] + angle_sin * mat[1][col];
mat[1][col] = -angle_sin * mat[0][col] + angle_cos * mat[1][col];
mat[0][col] = temp;
}
}
/* TODO: enum for axis? */
/**
* Rotate a matrix in-place.
@ -2408,12 +2390,6 @@ void rotate_m4(float mat[4][4], const char axis, const float angle)
}
}
void rescale_m3(float mat[3][3], const float scale[2])
{
mul_v3_fl(mat[0], scale[0]);
mul_v3_fl(mat[1], scale[1]);
}
/** Scale a matrix in-place. */
void rescale_m4(float mat[4][4], const float scale[3])
{
@ -2444,20 +2420,6 @@ void transform_pivot_set_m4(float mat[4][4], const float pivot[3])
mul_m4_m4m4(mat, mat, tmat);
}
void transform_pivot_set_m3(float mat[3][3], const float pivot[2])
{
float tmat[3][3];
unit_m3(tmat);
copy_v2_v2(tmat[2], pivot);
mul_m3_m3m3(mat, tmat, mat);
/* invert the matrix */
negate_v2(tmat[2]);
mul_m3_m3m3(mat, mat, tmat);
}
void blend_m3_m3m3(float out[3][3],
const float dst[3][3],
const float src[3][3],
@ -2637,21 +2599,6 @@ bool equals_m4m4(const float mat1[4][4], const float mat2[4][4])
equals_v4v4(mat1[2], mat2[2]) && equals_v4v4(mat1[3], mat2[3]));
}
/**
* Make a 3x3 matrix out of 3 transform components.
* Matrices are made in the order: `loc * rot * scale`
*/
void loc_rot_size_to_mat3(float R[3][3],
const float loc[2],
const float angle,
const float size[2])
{
unit_m3(R);
translate_m3(R, loc[0], loc[1]);
rotate_m3(R, angle);
rescale_m3(R, size);
}
/**
* Make a 4x4 matrix out of 3 transform components.
* Matrices are made in the order: `scale * rot * loc`

View File

@ -87,9 +87,8 @@ static TransData *SeqToTransData(const Scene *scene,
unit_m3(td->mtx);
unit_m3(td->smtx);
unit_m3(td->axismtx);
rotate_m3(td->axismtx, transform->rotation);
axis_angle_to_mat3_single(td->axismtx, 'Z', transform->rotation);
normalize_m3(td->axismtx);
tdseq->seq = seq;

View File

@ -652,7 +652,6 @@ static void gizmo2d_xform_invoke_prepare(const bContext *C,
float c[3] = {mid[0], mid[1], 0.0f};
float orient_matrix[3][3];
unit_m3(orient_matrix);
ScrArea *area = CTX_wm_area(C);
@ -673,7 +672,7 @@ static void gizmo2d_xform_invoke_prepare(const bContext *C,
rotate_around_center_v2(c, origin, ggd->rotation);
rotate_m3(orient_matrix, ggd->rotation);
axis_angle_to_mat3_single(orient_matrix, 'Z', ggd->rotation);
}
int orient_type = gizmo2d_calc_transform_orientation(C);

View File

@ -609,8 +609,7 @@ short transform_orientation_matrix_get(bContext *C,
Scene *scene = t->scene;
Sequence *seq = SEQ_select_active_get(scene);
if (seq && seq->strip->transform && orient_index == V3D_ORIENT_LOCAL) {
unit_m3(r_spacemtx);
rotate_m3(r_spacemtx, seq->strip->transform->rotation);
axis_angle_to_mat3_single(r_spacemtx, 'Z', seq->strip->transform->rotation);
return orient_index;
}
}

View File

@ -758,7 +758,7 @@ void IMB_processor_apply_threaded_scanlines(int total_scanlines,
void IMB_transform(struct ImBuf *src,
struct ImBuf *dst,
float transform_matrix[3][3],
float transform_matrix[4][4],
struct rctf *src_crop,
const eIMBInterpolationFilterMode filter);

View File

@ -374,36 +374,39 @@ typedef struct TransformUserData {
rctf src_crop;
} TransformUserData;
static void imb_transform_calc_start_uv(const float transform_matrix[3][3], float r_start_uv[2])
static void imb_transform_calc_start_uv(const float transform_matrix[4][4], float r_start_uv[2])
{
float orig[2];
orig[0] = 0.0f;
orig[1] = 0.0f;
mul_v2_m3v2(r_start_uv, transform_matrix, orig);
float r_start_uv_temp[3];
float orig[3];
zero_v3(orig);
mul_v3_m4v3(r_start_uv_temp, transform_matrix, orig);
copy_v2_v2(r_start_uv, r_start_uv_temp);
}
static void imb_transform_calc_add_x(const float transform_matrix[3][3],
static void imb_transform_calc_add_x(const float transform_matrix[4][4],
const float start_uv[2],
const int width,
float r_add_x[2])
{
float uv_max_x[2];
float uv_max_x[3];
zero_v3(uv_max_x);
uv_max_x[0] = width;
uv_max_x[1] = 0.0f;
mul_v2_m3v2(r_add_x, transform_matrix, uv_max_x);
mul_v3_m4v3(r_add_x, transform_matrix, uv_max_x);
sub_v2_v2(r_add_x, start_uv);
mul_v2_fl(r_add_x, 1.0f / width);
}
static void imb_transform_calc_add_y(const float transform_matrix[3][3],
static void imb_transform_calc_add_y(const float transform_matrix[4][4],
const float start_uv[2],
const int height,
float r_add_y[2])
{
float uv_max_y[2];
float uv_max_y[3];
zero_v3(uv_max_y);
uv_max_y[0] = 0.0f;
uv_max_y[1] = height;
mul_v2_m3v2(r_add_y, transform_matrix, uv_max_y);
mul_v3_m4v3(r_add_y, transform_matrix, uv_max_y);
sub_v2_v2(r_add_y, start_uv);
mul_v2_fl(r_add_y, 1.0f / height);
}
@ -480,7 +483,7 @@ static ScanlineThreadFunc imb_transform_scanline_func(const eIMBInterpolationFil
void IMB_transform(struct ImBuf *src,
struct ImBuf *dst,
float transform_matrix[3][3],
float transform_matrix[4][4],
struct rctf *src_crop,
const eIMBInterpolationFilterMode filter)
{

View File

@ -403,7 +403,7 @@ static void sequencer_image_crop_transform_matrix(const Sequence *seq,
const ImBuf *out,
const float image_scale_factor,
const float preview_scale_factor,
float r_transform_matrix[3][3])
float r_transform_matrix[4][4])
{
const StripTransform *transform = seq->strip->transform;
const float scale_x = transform->scale_x * image_scale_factor;
@ -412,13 +412,16 @@ static void sequencer_image_crop_transform_matrix(const Sequence *seq,
const float image_center_offs_y = (out->y - in->y) / 2;
const float translate_x = transform->xofs * preview_scale_factor + image_center_offs_x;
const float translate_y = transform->yofs * preview_scale_factor + image_center_offs_y;
const float pivot[2] = {in->x * transform->origin[0], in->y * transform->origin[1]};
loc_rot_size_to_mat3(r_transform_matrix,
(const float[]){translate_x, translate_y},
transform->rotation,
(const float[]){scale_x, scale_y});
transform_pivot_set_m3(r_transform_matrix, pivot);
invert_m3(r_transform_matrix);
const float pivot[3] = {in->x * transform->origin[0], in->y * transform->origin[1], 0.0f};
float rotation_matrix[3][3];
axis_angle_to_mat3_single(rotation_matrix, 'Z', transform->rotation);
loc_rot_size_to_mat4(r_transform_matrix,
(const float[]){translate_x, translate_y, 0.0f},
rotation_matrix,
(const float[]){scale_x, scale_y, 1.0f});
transform_pivot_set_m4(r_transform_matrix, pivot);
invert_m4(r_transform_matrix);
}
static void sequencer_image_crop_init(const Sequence *seq,
@ -438,20 +441,23 @@ static void sequencer_image_crop_init(const Sequence *seq,
static void sequencer_thumbnail_transform(ImBuf *in, ImBuf *out)
{
float image_scale_factor = (float)out->x / in->x;
float transform_matrix[3][3];
float transform_matrix[4][4];
/* Set to keep same loc,scale,rot but change scale to thumb size limit. */
const float scale_x = 1 * image_scale_factor;
const float scale_y = 1 * image_scale_factor;
const float image_center_offs_x = (out->x - in->x) / 2;
const float image_center_offs_y = (out->y - in->y) / 2;
const float pivot[2] = {in->x / 2, in->y / 2};
loc_rot_size_to_mat3(transform_matrix,
(const float[]){image_center_offs_x, image_center_offs_y},
0,
(const float[]){scale_x, scale_y});
transform_pivot_set_m3(transform_matrix, pivot);
invert_m3(transform_matrix);
const float pivot[3] = {in->x / 2, in->y / 2, 0.0f};
float rotation_matrix[3][3];
unit_m3(rotation_matrix);
loc_rot_size_to_mat4(transform_matrix,
(const float[]){image_center_offs_x, image_center_offs_y, 0.0f},
rotation_matrix,
(const float[]){scale_x, scale_y, 1.0f});
transform_pivot_set_m4(transform_matrix, pivot);
invert_m4(transform_matrix);
/* No crop. */
rctf source_crop;
@ -471,7 +477,7 @@ static void sequencer_preprocess_transform_crop(
const bool do_scale_to_render_size = seq_need_scale_to_render_size(seq, is_proxy_image);
const float image_scale_factor = do_scale_to_render_size ? 1.0f : preview_scale_factor;
float transform_matrix[3][3];
float transform_matrix[4][4];
sequencer_image_crop_transform_matrix(
seq, in, out, image_scale_factor, preview_scale_factor, transform_matrix);

View File

@ -490,36 +490,41 @@ static void seq_image_transform_quad_get_ex(const Scene *scene,
image_size[1] = seq->strip->stripdata->orig_height;
}
float transform_matrix[3][3];
loc_rot_size_to_mat3(transform_matrix,
(const float[]){transform->xofs, transform->yofs},
apply_rotation ? transform->rotation : 0.0f,
(const float[]){transform->scale_x, transform->scale_y});
float transform_matrix[4][4];
float rotation_matrix[3][3];
axis_angle_to_mat3_single(rotation_matrix, 'Z', apply_rotation ? transform->rotation : 0.0f);
loc_rot_size_to_mat4(transform_matrix,
(const float[]){transform->xofs, transform->yofs, 0.0f},
rotation_matrix,
(const float[]){transform->scale_x, transform->scale_y, 1.0f});
const float origin[2] = {image_size[0] * transform->origin[0],
image_size[1] * transform->origin[1]};
const float pivot[2] = {origin[0] - (image_size[0] / 2), origin[1] - (image_size[1] / 2)};
transform_pivot_set_m3(transform_matrix, pivot);
const float pivot[3] = {origin[0] - (image_size[0] / 2), origin[1] - (image_size[1] / 2), 0.0f};
transform_pivot_set_m4(transform_matrix, pivot);
r_quad[0][0] = (image_size[0] / 2) - crop->right;
r_quad[0][1] = (image_size[1] / 2) - crop->top;
r_quad[1][0] = (image_size[0] / 2) - crop->right;
r_quad[1][1] = (-image_size[1] / 2) + crop->bottom;
r_quad[2][0] = (-image_size[0] / 2) + crop->left;
r_quad[2][1] = (-image_size[1] / 2) + crop->bottom;
r_quad[3][0] = (-image_size[0] / 2) + crop->left;
r_quad[3][1] = (image_size[1] / 2) - crop->top;
float quad_temp[4][3];
for (int i = 0; i < 4; i++) {
zero_v2(quad_temp[i]);
}
mul_m3_v2(transform_matrix, r_quad[0]);
mul_m3_v2(transform_matrix, r_quad[1]);
mul_m3_v2(transform_matrix, r_quad[2]);
mul_m3_v2(transform_matrix, r_quad[3]);
quad_temp[0][0] = (image_size[0] / 2) - crop->right;
quad_temp[0][1] = (image_size[1] / 2) - crop->top;
quad_temp[1][0] = (image_size[0] / 2) - crop->right;
quad_temp[1][1] = (-image_size[1] / 2) + crop->bottom;
quad_temp[2][0] = (-image_size[0] / 2) + crop->left;
quad_temp[2][1] = (-image_size[1] / 2) + crop->bottom;
quad_temp[3][0] = (-image_size[0] / 2) + crop->left;
quad_temp[3][1] = (image_size[1] / 2) - crop->top;
float mirror[2];
SEQ_image_transform_mirror_factor_get(seq, mirror);
mul_v2_v2(r_quad[0], mirror);
mul_v2_v2(r_quad[1], mirror);
mul_v2_v2(r_quad[2], mirror);
mul_v2_v2(r_quad[3], mirror);
for (int i = 0; i < 4; i++) {
mul_m4_v3(transform_matrix, quad_temp[i]);
mul_v2_v2(quad_temp[i], mirror);
copy_v2_v2(r_quad[i], quad_temp[i]);
}
}
void SEQ_image_transform_quad_get(const Scene *scene,