Fix T81529: Can't move with constraint to a zero-size local axis
To fix the problem, it was necessary to create a fallback for the zero-sized axis in local orientation. This also affects the gizmos.
This commit is contained in:
parent
ea5f2f88b3
commit
569510d704
Notes:
blender-bot
2023-02-14 03:52:45 +01:00
Referenced by issue #81529, Impossible to move object in single axis local coordinate when one of the scales is 0 Referenced by issue #80169, Node wrangler highlighting artifacts
|
@ -425,7 +425,8 @@ static void applyAxisConstraintVec(
|
|||
else if (t->con.mode & CON_AXIS1) {
|
||||
copy_v3_v3(c, t->spacemtx[1]);
|
||||
}
|
||||
else if (t->con.mode & CON_AXIS2) {
|
||||
else {
|
||||
BLI_assert(t->con.mode & CON_AXIS2);
|
||||
copy_v3_v3(c, t->spacemtx[2]);
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
|
||||
/* Own include. */
|
||||
#include "transform_convert.h"
|
||||
#include "transform_orientations.h"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Object Mode Custom Data
|
||||
|
@ -183,8 +184,7 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
|
|||
}
|
||||
|
||||
/* axismtx has the real orientation */
|
||||
copy_m3_m4(td->axismtx, ob->obmat);
|
||||
normalize_m3(td->axismtx);
|
||||
transform_orientations_create_from_axis(td->axismtx, UNPACK3(ob->obmat));
|
||||
|
||||
td->con = ob->constraints.first;
|
||||
|
||||
|
|
|
@ -241,6 +241,54 @@ static TransformOrientation *createMeshSpace(bContext *C,
|
|||
return addMatrixSpace(C, mat, name, overwrite);
|
||||
}
|
||||
|
||||
bool transform_orientations_create_from_axis(float mat[3][3],
|
||||
const float x[3],
|
||||
const float y[3],
|
||||
const float z[3])
|
||||
{
|
||||
bool is_zero[3] = {true, true, true};
|
||||
zero_m3(mat);
|
||||
if (x) {
|
||||
is_zero[0] = normalize_v3_v3(mat[0], x) == 0.0f;
|
||||
}
|
||||
if (y) {
|
||||
is_zero[1] = normalize_v3_v3(mat[1], y) == 0.0f;
|
||||
}
|
||||
if (z) {
|
||||
is_zero[2] = normalize_v3_v3(mat[2], z) == 0.0f;
|
||||
}
|
||||
|
||||
int zero_axis = is_zero[0] + is_zero[1] + is_zero[2];
|
||||
if (zero_axis == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (zero_axis == 1) {
|
||||
int axis = is_zero[0] ? 0 : is_zero[1] ? 1 : 2;
|
||||
cross_v3_v3v3(mat[axis], mat[(axis + 1) % 3], mat[(axis + 2) % 3]);
|
||||
if (normalize_v3(mat[axis]) != 0.0f) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (zero_axis == 2) {
|
||||
int axis, a, b;
|
||||
axis = !is_zero[0] ? 0 : !is_zero[1] ? 1 : 2;
|
||||
a = (axis + 1) % 3;
|
||||
b = (axis + 2) % 3;
|
||||
|
||||
mat[a][a] = 1.0f;
|
||||
mat[b][b] = 1.0f;
|
||||
project_plane_v3_v3v3(mat[a], mat[a], mat[axis]);
|
||||
project_plane_v3_v3v3(mat[b], mat[b], mat[axis]);
|
||||
if ((normalize_v3(mat[a]) != 0.0f) && (normalize_v3(mat[b]) != 0.0f)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
unit_m3(mat);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool createSpaceNormal(float mat[3][3], const float normal[3])
|
||||
{
|
||||
float tangent[3] = {0.0f, 0.0f, 1.0f};
|
||||
|
@ -493,8 +541,7 @@ short ED_transform_calc_orientation_from_type_ex(const bContext *C,
|
|||
ED_getTransformOrientationMatrix(C, ob, obedit, pivot_point, r_mat);
|
||||
}
|
||||
else {
|
||||
copy_m3_m4(r_mat, ob->obmat);
|
||||
normalize_m3(r_mat);
|
||||
transform_orientations_create_from_axis(r_mat, UNPACK3(ob->obmat));
|
||||
}
|
||||
return V3D_ORIENT_LOCAL;
|
||||
}
|
||||
|
@ -607,7 +654,7 @@ void transform_orientations_current_set(TransInfo *t, const short orient_index)
|
|||
|
||||
BLI_strncpy(t->spacename, spacename, sizeof(t->spacename));
|
||||
copy_m3_m3(t->spacemtx, t->orient[orient_index].matrix);
|
||||
invert_m3_m3(t->spacemtx_inv, t->spacemtx);
|
||||
invert_m3_m3_safe_ortho(t->spacemtx_inv, t->spacemtx);
|
||||
t->orient_curr = orient_index;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,10 @@ const char *transform_orientations_spacename_get(struct TransInfo *t, const shor
|
|||
void transform_orientations_current_set(struct TransInfo *t, const short orient_index);
|
||||
|
||||
/* Those two fill in mat and return non-zero on success */
|
||||
bool transform_orientations_create_from_axis(float mat[3][3],
|
||||
const float x[3],
|
||||
const float y[3],
|
||||
const float z[3]);
|
||||
bool createSpaceNormal(float mat[3][3], const float normal[3]);
|
||||
bool createSpaceNormalTangent(float mat[3][3], const float normal[3], const float tangent[3]);
|
||||
|
||||
|
|
Loading…
Reference in New Issue