Refactor: Transform, reduce array bit size by removing TransData::ext
Now that the `t->data` and `t->data_ext` arrays have the same ordering, it is no longer necessary to include each member of `t->data_ext` in `t->data`. Access can be done using the same index. Pull Request: https://projects.blender.org/blender/blender/pulls/141563
This commit is contained in:
committed by
Germano Cavalcante
parent
145b2173bd
commit
ff9cc9c170
@@ -412,6 +412,7 @@ struct TransDataMirror : public TransDataBasic {
|
||||
float *loc_src;
|
||||
};
|
||||
|
||||
/** For objects, poses. 1 single allocation per #TransInfo! */
|
||||
struct TransDataExtension {
|
||||
/** Initial object drot. */
|
||||
float drot[3];
|
||||
@@ -506,8 +507,6 @@ struct TransData : public TransDataBasic {
|
||||
float axismtx[3][3];
|
||||
/** For objects/bones, the first constraint in its constraint stack. */
|
||||
bConstraint *con;
|
||||
/** For objects, poses. 1 single allocation per #TransInfo! */
|
||||
TransDataExtension *ext;
|
||||
/** For curves, stores handle flags for modification/cancel. */
|
||||
TransDataCurveHandleFlags *hdata;
|
||||
/** If set, copy of Object or #bPoseChannel protection. */
|
||||
@@ -1088,7 +1087,6 @@ void postTrans(bContext *C, TransInfo *t);
|
||||
void resetTransModal(TransInfo *t);
|
||||
void resetTransRestrictions(TransInfo *t);
|
||||
|
||||
void applyTransObjects(TransInfo *t);
|
||||
void restoreTransObjects(TransInfo *t);
|
||||
|
||||
void calculateCenter2D(TransInfo *t);
|
||||
@@ -1119,7 +1117,10 @@ void calculatePropRatio(TransInfo *t);
|
||||
* (use for objects or pose-bones)
|
||||
* Similar to #ElementRotation.
|
||||
*/
|
||||
void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot);
|
||||
void transform_data_ext_rotate(TransData *td,
|
||||
TransDataExtension *td_ext,
|
||||
float mat[3][3],
|
||||
bool use_drot);
|
||||
|
||||
Object *transform_object_deform_pose_armature_get(const TransInfo *t, Object *ob);
|
||||
|
||||
|
||||
@@ -357,13 +357,14 @@ static short transform_orientation_or_default(const TransInfo *t)
|
||||
}
|
||||
|
||||
static const float (*transform_object_axismtx_get(const TransInfo *t,
|
||||
const TransDataContainer * /*tc*/,
|
||||
const TransDataContainer *tc,
|
||||
const TransData *td))[3]
|
||||
{
|
||||
if (transform_orientation_or_default(t) == V3D_ORIENT_GIMBAL) {
|
||||
BLI_assert(t->orient_type_mask & (1 << V3D_ORIENT_GIMBAL));
|
||||
if (t->options & (CTX_POSE_BONE | CTX_OBJECT)) {
|
||||
return td->ext->axismtx_gimbal;
|
||||
TransDataExtension *td_ext = &tc->data_ext[td - tc->data];
|
||||
return td_ext->axismtx_gimbal;
|
||||
}
|
||||
}
|
||||
return td->axismtx;
|
||||
|
||||
@@ -389,7 +389,8 @@ static void pose_mirror_info_init(PoseInitData_Mirror *pid,
|
||||
/** \name Convert Armature
|
||||
* \{ */
|
||||
|
||||
static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, TransData *td)
|
||||
static void add_pose_transdata(
|
||||
TransInfo *t, bPoseChannel *pchan, Object *ob, TransData *td, TransDataExtension *td_ext)
|
||||
{
|
||||
Bone *bone = pchan->bone;
|
||||
float pmat[3][3], omat[3][3];
|
||||
@@ -415,35 +416,35 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
|
||||
td->loc = pchan->loc;
|
||||
copy_v3_v3(td->iloc, pchan->loc);
|
||||
|
||||
td->ext->scale = pchan->scale;
|
||||
copy_v3_v3(td->ext->iscale, pchan->scale);
|
||||
td_ext->scale = pchan->scale;
|
||||
copy_v3_v3(td_ext->iscale, pchan->scale);
|
||||
|
||||
if (pchan->rotmode > 0) {
|
||||
td->ext->rot = pchan->eul;
|
||||
td->ext->rotAxis = nullptr;
|
||||
td->ext->rotAngle = nullptr;
|
||||
td->ext->quat = nullptr;
|
||||
td_ext->rot = pchan->eul;
|
||||
td_ext->rotAxis = nullptr;
|
||||
td_ext->rotAngle = nullptr;
|
||||
td_ext->quat = nullptr;
|
||||
|
||||
copy_v3_v3(td->ext->irot, pchan->eul);
|
||||
copy_v3_v3(td_ext->irot, pchan->eul);
|
||||
}
|
||||
else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
|
||||
td->ext->rot = nullptr;
|
||||
td->ext->rotAxis = pchan->rotAxis;
|
||||
td->ext->rotAngle = &pchan->rotAngle;
|
||||
td->ext->quat = nullptr;
|
||||
td_ext->rot = nullptr;
|
||||
td_ext->rotAxis = pchan->rotAxis;
|
||||
td_ext->rotAngle = &pchan->rotAngle;
|
||||
td_ext->quat = nullptr;
|
||||
|
||||
td->ext->irotAngle = pchan->rotAngle;
|
||||
copy_v3_v3(td->ext->irotAxis, pchan->rotAxis);
|
||||
td_ext->irotAngle = pchan->rotAngle;
|
||||
copy_v3_v3(td_ext->irotAxis, pchan->rotAxis);
|
||||
}
|
||||
else {
|
||||
td->ext->rot = nullptr;
|
||||
td->ext->rotAxis = nullptr;
|
||||
td->ext->rotAngle = nullptr;
|
||||
td->ext->quat = pchan->quat;
|
||||
td_ext->rot = nullptr;
|
||||
td_ext->rotAxis = nullptr;
|
||||
td_ext->rotAngle = nullptr;
|
||||
td_ext->quat = pchan->quat;
|
||||
|
||||
copy_qt_qt(td->ext->iquat, pchan->quat);
|
||||
copy_qt_qt(td_ext->iquat, pchan->quat);
|
||||
}
|
||||
td->ext->rotOrder = pchan->rotmode;
|
||||
td_ext->rotOrder = pchan->rotmode;
|
||||
|
||||
/* Proper way to get parent transform + our own transform + constraints transform. */
|
||||
copy_m3_m4(omat, ob->object_to_world().ptr());
|
||||
@@ -471,13 +472,13 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
|
||||
copy_m3_m4(tmat, pchan->constinv);
|
||||
invert_m3_m3(cmat, tmat);
|
||||
mul_m3_series(td->mtx, cmat, omat, pmat);
|
||||
mul_m3_series(td->ext->r_mtx, cmat, omat, rpmat);
|
||||
mul_m3_series(td_ext->r_mtx, cmat, omat, rpmat);
|
||||
}
|
||||
else {
|
||||
mul_m3_series(td->mtx, omat, pmat);
|
||||
mul_m3_series(td->ext->r_mtx, omat, rpmat);
|
||||
mul_m3_series(td_ext->r_mtx, omat, rpmat);
|
||||
}
|
||||
invert_m3_m3(td->ext->r_smtx, td->ext->r_mtx);
|
||||
invert_m3_m3(td_ext->r_smtx, td_ext->r_mtx);
|
||||
}
|
||||
|
||||
pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
|
||||
@@ -489,7 +490,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
|
||||
if (pchan->parent) {
|
||||
/* Same as `td->smtx` but without `pchan->bone->bone_mat`. */
|
||||
td->flag |= TD_PBONE_LOCAL_MTX_C;
|
||||
mul_m3_m3m3(td->ext->l_smtx, pchan->bone->bone_mat, td->smtx);
|
||||
mul_m3_m3m3(td_ext->l_smtx, pchan->bone->bone_mat, td->smtx);
|
||||
}
|
||||
else {
|
||||
td->flag |= TD_PBONE_LOCAL_MTX_P;
|
||||
@@ -502,8 +503,8 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
|
||||
normalize_m3(td->axismtx);
|
||||
|
||||
if (t->orient_type_mask & (1 << V3D_ORIENT_GIMBAL)) {
|
||||
if (!gimbal_axis_pose(ob, pchan, td->ext->axismtx_gimbal)) {
|
||||
copy_m3_m3(td->ext->axismtx_gimbal, td->axismtx);
|
||||
if (!gimbal_axis_pose(ob, pchan, td_ext->axismtx_gimbal)) {
|
||||
copy_m3_m3(td_ext->axismtx_gimbal, td->axismtx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -659,7 +660,6 @@ static void createTransPose(bContext * /*C*/, TransInfo *t)
|
||||
Object *ob = tc->poseobj;
|
||||
TransData *td;
|
||||
TransDataExtension *tdx;
|
||||
int i;
|
||||
|
||||
PoseInitData_Mirror *pid = static_cast<PoseInitData_Mirror *>(tc->custom.type.data);
|
||||
int pid_index = 0;
|
||||
@@ -678,10 +678,6 @@ static void createTransPose(bContext * /*C*/, TransInfo *t)
|
||||
/* Initialize trans data. */
|
||||
td = tc->data = MEM_calloc_arrayN<TransData>(tc->data_len, "TransPoseBone");
|
||||
tdx = tc->data_ext = MEM_calloc_arrayN<TransDataExtension>(tc->data_len, "TransPoseBoneExt");
|
||||
for (i = 0; i < tc->data_len; i++, td++, tdx++) {
|
||||
td->ext = tdx;
|
||||
td->val = nullptr;
|
||||
}
|
||||
|
||||
if (mirror) {
|
||||
LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
|
||||
@@ -706,10 +702,10 @@ static void createTransPose(bContext * /*C*/, TransInfo *t)
|
||||
|
||||
/* Use pose channels to fill trans data. */
|
||||
td = tc->data;
|
||||
tdx = tc->data_ext;
|
||||
LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
|
||||
if (pchan->bone->flag & BONE_TRANSFORM) {
|
||||
add_pose_transdata(t, pchan, ob, td);
|
||||
td++;
|
||||
add_pose_transdata(t, pchan, ob, td++, tdx++);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -836,7 +832,6 @@ static void createTransArmatureVerts(bContext * /*C*/, TransInfo *t)
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
|
||||
td->loc = nullptr;
|
||||
td->ext = nullptr;
|
||||
|
||||
td++;
|
||||
}
|
||||
@@ -850,7 +845,6 @@ static void createTransArmatureVerts(bContext * /*C*/, TransInfo *t)
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
|
||||
td->loc = nullptr;
|
||||
td->ext = nullptr;
|
||||
|
||||
td++;
|
||||
}
|
||||
@@ -879,8 +873,6 @@ static void createTransArmatureVerts(bContext * /*C*/, TransInfo *t)
|
||||
copy_m3_m3(td->axismtx, td->mtx);
|
||||
normalize_m3(td->axismtx);
|
||||
|
||||
td->ext = nullptr;
|
||||
|
||||
td++;
|
||||
}
|
||||
}
|
||||
@@ -893,8 +885,6 @@ static void createTransArmatureVerts(bContext * /*C*/, TransInfo *t)
|
||||
copy_v3_v3(td->center, ebo->head);
|
||||
td->flag = TD_SELECTED;
|
||||
|
||||
td->ext = nullptr;
|
||||
|
||||
td++;
|
||||
}
|
||||
}
|
||||
@@ -931,7 +921,6 @@ static void createTransArmatureVerts(bContext * /*C*/, TransInfo *t)
|
||||
td->ival = ebo->roll;
|
||||
}
|
||||
|
||||
td->ext = nullptr;
|
||||
td->val = nullptr;
|
||||
|
||||
td++;
|
||||
@@ -953,7 +942,6 @@ static void createTransArmatureVerts(bContext * /*C*/, TransInfo *t)
|
||||
td->extra = ebo; /* To fix roll. */
|
||||
td->ival = ebo->roll;
|
||||
|
||||
td->ext = nullptr;
|
||||
td->val = nullptr;
|
||||
|
||||
td++;
|
||||
|
||||
@@ -38,7 +38,6 @@ static void createTransCursor_2D_impl(TransInfo *t, float cursor_location[2])
|
||||
tc->data_len = 1;
|
||||
td = tc->data = MEM_callocN<TransData>("TransTexspace");
|
||||
td2d = tc->data_2d = MEM_calloc_arrayN<TransData2D>(tc->data_len, "TransObData2D(Cursor)");
|
||||
td->ext = tc->data_ext = MEM_callocN<TransDataExtension>("TransCursorExt");
|
||||
}
|
||||
|
||||
td->flag = TD_SELECTED;
|
||||
@@ -124,6 +123,7 @@ static void recalcData_cursor_sequencer(TransInfo *t)
|
||||
static void createTransCursor_view3d(bContext * /*C*/, TransInfo *t)
|
||||
{
|
||||
TransData *td;
|
||||
TransDataExtension *td_ext;
|
||||
|
||||
Scene *scene = t->scene;
|
||||
if (!ID_IS_EDITABLE(scene)) {
|
||||
@@ -137,7 +137,7 @@ static void createTransCursor_view3d(bContext * /*C*/, TransInfo *t)
|
||||
TransDataContainer *tc = t->data_container;
|
||||
tc->data_len = 1;
|
||||
td = tc->data = MEM_callocN<TransData>("TransTexspace");
|
||||
td->ext = tc->data_ext = MEM_callocN<TransDataExtension>("TransTexspace");
|
||||
td_ext = tc->data_ext = MEM_callocN<TransDataExtension>("TransTexspace");
|
||||
}
|
||||
|
||||
td->flag = TD_SELECTED;
|
||||
@@ -152,31 +152,31 @@ static void createTransCursor_view3d(bContext * /*C*/, TransInfo *t)
|
||||
copy_v3_v3(td->iloc, cursor->location);
|
||||
|
||||
if (cursor->rotation_mode > 0) {
|
||||
td->ext->rot = cursor->rotation_euler;
|
||||
td->ext->rotAxis = nullptr;
|
||||
td->ext->rotAngle = nullptr;
|
||||
td->ext->quat = nullptr;
|
||||
td_ext->rot = cursor->rotation_euler;
|
||||
td_ext->rotAxis = nullptr;
|
||||
td_ext->rotAngle = nullptr;
|
||||
td_ext->quat = nullptr;
|
||||
|
||||
copy_v3_v3(td->ext->irot, cursor->rotation_euler);
|
||||
copy_v3_v3(td_ext->irot, cursor->rotation_euler);
|
||||
}
|
||||
else if (cursor->rotation_mode == ROT_MODE_AXISANGLE) {
|
||||
td->ext->rot = nullptr;
|
||||
td->ext->rotAxis = cursor->rotation_axis;
|
||||
td->ext->rotAngle = &cursor->rotation_angle;
|
||||
td->ext->quat = nullptr;
|
||||
td_ext->rot = nullptr;
|
||||
td_ext->rotAxis = cursor->rotation_axis;
|
||||
td_ext->rotAngle = &cursor->rotation_angle;
|
||||
td_ext->quat = nullptr;
|
||||
|
||||
td->ext->irotAngle = cursor->rotation_angle;
|
||||
copy_v3_v3(td->ext->irotAxis, cursor->rotation_axis);
|
||||
td_ext->irotAngle = cursor->rotation_angle;
|
||||
copy_v3_v3(td_ext->irotAxis, cursor->rotation_axis);
|
||||
}
|
||||
else {
|
||||
td->ext->rot = nullptr;
|
||||
td->ext->rotAxis = nullptr;
|
||||
td->ext->rotAngle = nullptr;
|
||||
td->ext->quat = cursor->rotation_quaternion;
|
||||
td_ext->rot = nullptr;
|
||||
td_ext->rotAxis = nullptr;
|
||||
td_ext->rotAngle = nullptr;
|
||||
td_ext->quat = cursor->rotation_quaternion;
|
||||
|
||||
copy_qt_qt(td->ext->iquat, cursor->rotation_quaternion);
|
||||
copy_qt_qt(td_ext->iquat, cursor->rotation_quaternion);
|
||||
}
|
||||
td->ext->rotOrder = cursor->rotation_mode;
|
||||
td_ext->rotOrder = cursor->rotation_mode;
|
||||
}
|
||||
|
||||
static void recalcData_cursor_view3d(TransInfo *t)
|
||||
|
||||
@@ -227,7 +227,6 @@ static void createTransCurveVerts(bContext * /*C*/, TransInfo *t)
|
||||
td->flag = 0;
|
||||
}
|
||||
}
|
||||
td->ext = nullptr;
|
||||
td->val = nullptr;
|
||||
|
||||
hdata = initTransDataCurveHandles(td, bezt);
|
||||
@@ -253,7 +252,6 @@ static void createTransCurveVerts(bContext * /*C*/, TransInfo *t)
|
||||
else {
|
||||
td->flag = 0;
|
||||
}
|
||||
td->ext = nullptr;
|
||||
|
||||
/* TODO: make points scale. */
|
||||
if (t->mode == TFM_CURVE_SHRINKFATTEN /* `|| t->mode == TFM_RESIZE` */) {
|
||||
@@ -309,7 +307,6 @@ static void createTransCurveVerts(bContext * /*C*/, TransInfo *t)
|
||||
td->flag = 0;
|
||||
}
|
||||
}
|
||||
td->ext = nullptr;
|
||||
td->val = nullptr;
|
||||
|
||||
if (hdata == nullptr) {
|
||||
@@ -345,7 +342,6 @@ static void createTransCurveVerts(bContext * /*C*/, TransInfo *t)
|
||||
else {
|
||||
td->flag = 0;
|
||||
}
|
||||
td->ext = nullptr;
|
||||
|
||||
if (ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_RESIZE)) {
|
||||
td->val = &(bp->radius);
|
||||
|
||||
@@ -629,7 +629,6 @@ void curve_populate_trans_data_structs(const TransInfo &t,
|
||||
td.val = value;
|
||||
td.ival = *value;
|
||||
}
|
||||
td.ext = nullptr;
|
||||
|
||||
if (deformation.deform_mats.is_empty()) {
|
||||
copy_m3_m3(td.smtx, smtx_base.ptr());
|
||||
|
||||
@@ -110,7 +110,6 @@ static void bezt_to_transdata(TransData *td,
|
||||
memset(td->axismtx, 0, sizeof(td->axismtx));
|
||||
td->axismtx[2][2] = 1.0f;
|
||||
|
||||
td->ext = nullptr;
|
||||
td->val = nullptr;
|
||||
|
||||
/* Store AnimData info in td->extra, for applying mapping when flushing.
|
||||
|
||||
@@ -98,7 +98,6 @@ static void createTransLatticeVerts(bContext * /*C*/, TransInfo *t)
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
|
||||
td->ext = nullptr;
|
||||
td->val = nullptr;
|
||||
|
||||
td++;
|
||||
|
||||
@@ -90,7 +90,6 @@ static void MaskHandleToTransData(MaskSplinePoint *point,
|
||||
memset(td->axismtx, 0, sizeof(td->axismtx));
|
||||
td->axismtx[2][2] = 1.0f;
|
||||
|
||||
td->ext = nullptr;
|
||||
td->val = nullptr;
|
||||
|
||||
if (is_sel_any) {
|
||||
@@ -156,8 +155,6 @@ static void MaskPointToTransData(Scene *scene,
|
||||
memset(td->axismtx, 0, sizeof(td->axismtx));
|
||||
td->axismtx[2][2] = 1.0f;
|
||||
|
||||
td->ext = nullptr;
|
||||
|
||||
if (i == 1) {
|
||||
/* Scaling weights. */
|
||||
td->val = &bezt->weight;
|
||||
|
||||
@@ -88,8 +88,6 @@ static void createTransMBallVerts(bContext * /*C*/, TransInfo *t)
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
|
||||
td->ext = tx;
|
||||
|
||||
/* Radius of MetaElem (mass of MetaElem influence). */
|
||||
if (ml->flag & MB_SCALE_RAD) {
|
||||
td->val = &ml->rad;
|
||||
|
||||
@@ -1474,11 +1474,9 @@ static void VertsToTransData(TransInfo *t,
|
||||
td->axismtx[1][1] = td->axismtx[1][2] = 0.0f;
|
||||
}
|
||||
|
||||
td->ext = nullptr;
|
||||
td->val = nullptr;
|
||||
td->extra = eve;
|
||||
if (t->mode == TFM_SHRINKFATTEN) {
|
||||
td->ext = tx;
|
||||
tx->iscale[0] = BM_vert_calc_shell_factor_ex(eve, no, BM_ELEM_SELECT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,8 +104,6 @@ static void createTransEdge(bContext * /*C*/, TransInfo *t)
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
|
||||
td->ext = nullptr;
|
||||
|
||||
fl_ptr = static_cast<float *>(BM_ELEM_CD_GET_VOID_P(eed, cd_edge_float_offset));
|
||||
td->val = fl_ptr;
|
||||
td->ival = *fl_ptr;
|
||||
|
||||
@@ -61,7 +61,6 @@ static void UVsToTransData(const float aspect[2],
|
||||
memset(r_td->axismtx, 0, sizeof(r_td->axismtx));
|
||||
r_td->axismtx[2][2] = 1.0f;
|
||||
|
||||
r_td->ext = nullptr;
|
||||
r_td->val = nullptr;
|
||||
|
||||
if (selected) {
|
||||
|
||||
@@ -74,7 +74,6 @@ static void create_transform_data_for_node(TransData &td,
|
||||
memset(td.axismtx, 0, sizeof(td.axismtx));
|
||||
td.axismtx[2][2] = 1.0f;
|
||||
|
||||
td.ext = nullptr;
|
||||
td.val = nullptr;
|
||||
|
||||
td.flag = TD_SELECTED;
|
||||
|
||||
@@ -139,7 +139,7 @@ static void trans_obchild_in_obmode_update_all(TransInfo *t)
|
||||
/**
|
||||
* Transcribe given object into TransData for Transforming.
|
||||
*/
|
||||
static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
|
||||
static void ObjectToTransData(TransInfo *t, TransData *td, TransDataExtension *td_ext, Object *ob)
|
||||
{
|
||||
Scene *scene = t->scene;
|
||||
bool constinv;
|
||||
@@ -154,17 +154,17 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
|
||||
if (BKE_rigidbody_check_sim_running(scene->rigidbody_world, ctime)) {
|
||||
|
||||
/* Save original object transform. */
|
||||
copy_v3_v3(td->ext->oloc, ob->loc);
|
||||
copy_v3_v3(td_ext->oloc, ob->loc);
|
||||
|
||||
if (ob->rotmode > 0) {
|
||||
copy_v3_v3(td->ext->orot, ob->rot);
|
||||
copy_v3_v3(td_ext->orot, ob->rot);
|
||||
}
|
||||
else if (ob->rotmode == ROT_MODE_AXISANGLE) {
|
||||
td->ext->orotAngle = ob->rotAngle;
|
||||
copy_v3_v3(td->ext->orotAxis, ob->rotAxis);
|
||||
td_ext->orotAngle = ob->rotAngle;
|
||||
copy_v3_v3(td_ext->orotAxis, ob->rotAxis);
|
||||
}
|
||||
else {
|
||||
copy_qt_qt(td->ext->oquat, ob->quat);
|
||||
copy_qt_qt(td_ext->oquat, ob->quat);
|
||||
}
|
||||
/* Update object's loc/rot to get current rigid body transform. */
|
||||
mat4_to_loc_rot_size(ob->loc, rot, scale, ob->object_to_world().ptr());
|
||||
@@ -176,8 +176,8 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
|
||||
/* `axismtx` has the real orientation. */
|
||||
transform_orientations_create_from_axis(td->axismtx, UNPACK3(ob->object_to_world().ptr()));
|
||||
if (t->orient_type_mask & (1 << V3D_ORIENT_GIMBAL)) {
|
||||
if (!gimbal_axis_object(ob, td->ext->axismtx_gimbal)) {
|
||||
copy_m3_m3(td->ext->axismtx_gimbal, td->axismtx);
|
||||
if (!gimbal_axis_object(ob, td_ext->axismtx_gimbal)) {
|
||||
copy_m3_m3(td_ext->axismtx_gimbal, td->axismtx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,46 +228,46 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
|
||||
copy_v3_v3(td->iloc, td->loc);
|
||||
|
||||
if (ob->rotmode > 0) {
|
||||
td->ext->rot = ob->rot;
|
||||
td->ext->rotAxis = nullptr;
|
||||
td->ext->rotAngle = nullptr;
|
||||
td->ext->quat = nullptr;
|
||||
td_ext->rot = ob->rot;
|
||||
td_ext->rotAxis = nullptr;
|
||||
td_ext->rotAngle = nullptr;
|
||||
td_ext->quat = nullptr;
|
||||
|
||||
copy_v3_v3(td->ext->irot, ob->rot);
|
||||
copy_v3_v3(td->ext->drot, ob->drot);
|
||||
copy_v3_v3(td_ext->irot, ob->rot);
|
||||
copy_v3_v3(td_ext->drot, ob->drot);
|
||||
}
|
||||
else if (ob->rotmode == ROT_MODE_AXISANGLE) {
|
||||
td->ext->rot = nullptr;
|
||||
td->ext->rotAxis = ob->rotAxis;
|
||||
td->ext->rotAngle = &ob->rotAngle;
|
||||
td->ext->quat = nullptr;
|
||||
td_ext->rot = nullptr;
|
||||
td_ext->rotAxis = ob->rotAxis;
|
||||
td_ext->rotAngle = &ob->rotAngle;
|
||||
td_ext->quat = nullptr;
|
||||
|
||||
td->ext->irotAngle = ob->rotAngle;
|
||||
copy_v3_v3(td->ext->irotAxis, ob->rotAxis);
|
||||
td_ext->irotAngle = ob->rotAngle;
|
||||
copy_v3_v3(td_ext->irotAxis, ob->rotAxis);
|
||||
/* XXX, not implemented. */
|
||||
#if 0
|
||||
td->ext->drotAngle = ob->drotAngle;
|
||||
copy_v3_v3(td->ext->drotAxis, ob->drotAxis);
|
||||
td_ext->drotAngle = ob->drotAngle;
|
||||
copy_v3_v3(td_ext->drotAxis, ob->drotAxis);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
td->ext->rot = nullptr;
|
||||
td->ext->rotAxis = nullptr;
|
||||
td->ext->rotAngle = nullptr;
|
||||
td->ext->quat = ob->quat;
|
||||
td_ext->rot = nullptr;
|
||||
td_ext->rotAxis = nullptr;
|
||||
td_ext->rotAngle = nullptr;
|
||||
td_ext->quat = ob->quat;
|
||||
|
||||
copy_qt_qt(td->ext->iquat, ob->quat);
|
||||
copy_qt_qt(td->ext->dquat, ob->dquat);
|
||||
copy_qt_qt(td_ext->iquat, ob->quat);
|
||||
copy_qt_qt(td_ext->dquat, ob->dquat);
|
||||
}
|
||||
td->ext->rotOrder = ob->rotmode;
|
||||
td_ext->rotOrder = ob->rotmode;
|
||||
|
||||
td->ext->scale = ob->scale;
|
||||
copy_v3_v3(td->ext->iscale, ob->scale);
|
||||
copy_v3_v3(td->ext->dscale, ob->dscale);
|
||||
td_ext->scale = ob->scale;
|
||||
copy_v3_v3(td_ext->iscale, ob->scale);
|
||||
copy_v3_v3(td_ext->dscale, ob->dscale);
|
||||
|
||||
copy_v3_v3(td->center, ob->object_to_world().location());
|
||||
|
||||
copy_m4_m4(td->ext->obmat, ob->object_to_world().ptr());
|
||||
copy_m4_m4(td_ext->obmat, ob->object_to_world().ptr());
|
||||
|
||||
/* Is there a need to set the global<->data space conversion matrices? */
|
||||
if (ob->parent || constinv) {
|
||||
@@ -534,8 +534,7 @@ static void createTransObject(bContext *C, TransInfo *t)
|
||||
|
||||
td->flag = TD_SELECTED;
|
||||
td->protectflag = ob->protectflag;
|
||||
td->ext = tx;
|
||||
td->ext->rotOrder = ob->rotmode;
|
||||
tx->rotOrder = ob->rotmode;
|
||||
|
||||
if (base->flag & BA_TRANSFORM_CHILD) {
|
||||
td->flag |= TD_NOCENTER;
|
||||
@@ -565,7 +564,7 @@ static void createTransObject(bContext *C, TransInfo *t)
|
||||
}
|
||||
}
|
||||
|
||||
ObjectToTransData(t, td, ob);
|
||||
ObjectToTransData(t, td, tx, ob);
|
||||
td->val = nullptr;
|
||||
td++;
|
||||
tx++;
|
||||
@@ -588,10 +587,9 @@ static void createTransObject(bContext *C, TransInfo *t)
|
||||
BASE_SELECTABLE(v3d, base))
|
||||
{
|
||||
td->protectflag = ob->protectflag;
|
||||
td->ext = tx;
|
||||
td->ext->rotOrder = ob->rotmode;
|
||||
tx->rotOrder = ob->rotmode;
|
||||
|
||||
ObjectToTransData(t, td, ob);
|
||||
ObjectToTransData(t, td, tx, ob);
|
||||
td->val = nullptr;
|
||||
td++;
|
||||
tx++;
|
||||
@@ -906,6 +904,7 @@ static void special_aftertrans_update__object(bContext *C, TransInfo *t)
|
||||
|
||||
for (int i = 0; i < tc->data_len; i++) {
|
||||
TransData *td = tc->data + i;
|
||||
TransDataExtension *td_ext = tc->data_ext + i;
|
||||
ListBase pidlist;
|
||||
ob = static_cast<Object *>(td->extra);
|
||||
|
||||
@@ -945,12 +944,8 @@ static void special_aftertrans_update__object(bContext *C, TransInfo *t)
|
||||
if (ob->rigidbody_object && canceled) {
|
||||
float ctime = BKE_scene_ctime_get(t->scene);
|
||||
if (BKE_rigidbody_check_sim_running(t->scene->rigidbody_world, ctime)) {
|
||||
BKE_rigidbody_aftertrans_update(ob,
|
||||
td->ext->oloc,
|
||||
td->ext->orot,
|
||||
td->ext->oquat,
|
||||
td->ext->orotAxis,
|
||||
td->ext->orotAngle);
|
||||
BKE_rigidbody_aftertrans_update(
|
||||
ob, td_ext->oloc, td_ext->orot, td_ext->oquat, td_ext->orotAxis, td_ext->orotAngle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ static void createTransTexspace(bContext * /*C*/, TransInfo *t)
|
||||
{
|
||||
ViewLayer *view_layer = t->view_layer;
|
||||
TransData *td;
|
||||
TransDataExtension *td_ext;
|
||||
Object *ob;
|
||||
ID *id;
|
||||
char *texspace_flag;
|
||||
@@ -63,7 +64,7 @@ static void createTransTexspace(bContext * /*C*/, TransInfo *t)
|
||||
TransDataContainer *tc = t->data_container;
|
||||
tc->data_len = 1;
|
||||
td = tc->data = MEM_callocN<TransData>("TransTexspace");
|
||||
td->ext = tc->data_ext = MEM_callocN<TransDataExtension>("TransTexspace");
|
||||
td_ext = tc->data_ext = MEM_callocN<TransDataExtension>("TransTexspace");
|
||||
}
|
||||
|
||||
td->flag = TD_SELECTED;
|
||||
@@ -74,14 +75,14 @@ static void createTransTexspace(bContext * /*C*/, TransInfo *t)
|
||||
normalize_m3(td->axismtx);
|
||||
pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
|
||||
|
||||
if (BKE_object_obdata_texspace_get(ob, &texspace_flag, &td->loc, &td->ext->scale)) {
|
||||
if (BKE_object_obdata_texspace_get(ob, &texspace_flag, &td->loc, &td_ext->scale)) {
|
||||
ob->dtx |= OB_TEXSPACE;
|
||||
*texspace_flag &= ~ME_TEXSPACE_FLAG_AUTO;
|
||||
}
|
||||
|
||||
copy_v3_v3(td->iloc, td->loc);
|
||||
copy_v3_v3(td->center, td->loc);
|
||||
copy_v3_v3(td->ext->iscale, td->ext->scale);
|
||||
copy_v3_v3(td_ext->iscale, td_ext->scale);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -48,7 +48,6 @@ static void PaintCurveConvertHandle(
|
||||
memset(td->axismtx, 0, sizeof(td->axismtx));
|
||||
td->axismtx[2][2] = 1.0f;
|
||||
|
||||
td->ext = nullptr;
|
||||
td->val = nullptr;
|
||||
td->flag |= TD_SELECTED;
|
||||
td->dist = 0.0;
|
||||
@@ -82,7 +81,6 @@ static void PaintCurvePointToTransData(PaintCurvePoint *pcp,
|
||||
memset(td->axismtx, 0, sizeof(td->axismtx));
|
||||
td->axismtx[2][2] = 1.0f;
|
||||
|
||||
td->ext = nullptr;
|
||||
td->val = nullptr;
|
||||
td->flag |= TD_SELECTED;
|
||||
td->dist = 0.0;
|
||||
|
||||
@@ -143,7 +143,6 @@ static void createTransParticleVerts(bContext * /*C*/, TransInfo *t)
|
||||
td->protectflag |= OB_LOCK_LOC;
|
||||
}
|
||||
|
||||
td->ext = tx;
|
||||
if (t->mode == TFM_BAKE_TIME) {
|
||||
td->val = key->time;
|
||||
td->ival = *(key->time);
|
||||
|
||||
@@ -116,7 +116,6 @@ static void createTransPointCloudVerts(bContext * /*C*/, TransInfo *t)
|
||||
td.val = value;
|
||||
td.ival = *value;
|
||||
}
|
||||
td.ext = nullptr;
|
||||
|
||||
copy_m3_m3(td.smtx, smtx_base.ptr());
|
||||
copy_m3_m3(td.mtx, mtx_base.ptr());
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace blender::ed::transform {
|
||||
static void createTransSculpt(bContext *C, TransInfo *t)
|
||||
{
|
||||
TransData *td;
|
||||
TransDataExtension *td_ext;
|
||||
|
||||
Scene *scene = t->scene;
|
||||
if (!BKE_id_is_editable(CTX_data_main(C), &scene->id)) {
|
||||
@@ -54,7 +55,7 @@ static void createTransSculpt(bContext *C, TransInfo *t)
|
||||
tc->data_len = 1;
|
||||
tc->is_active = true;
|
||||
td = tc->data = MEM_callocN<TransData>(__func__);
|
||||
td->ext = tc->data_ext = MEM_callocN<TransDataExtension>(__func__);
|
||||
td_ext = tc->data_ext = MEM_callocN<TransDataExtension>(__func__);
|
||||
}
|
||||
|
||||
td->flag = TD_SELECTED;
|
||||
@@ -72,24 +73,24 @@ static void createTransSculpt(bContext *C, TransInfo *t)
|
||||
copy_m3_m4(obmat_inv, ob.object_to_world().ptr());
|
||||
invert_m3(obmat_inv);
|
||||
|
||||
td->ext->rot = nullptr;
|
||||
td->ext->rotAxis = nullptr;
|
||||
td->ext->rotAngle = nullptr;
|
||||
td->ext->quat = ss.pivot_rot;
|
||||
copy_m4_m4(td->ext->obmat, ob.object_to_world().ptr());
|
||||
copy_m3_m3(td->ext->l_smtx, obmat_inv);
|
||||
copy_m3_m4(td->ext->r_mtx, ob.object_to_world().ptr());
|
||||
copy_m3_m3(td->ext->r_smtx, obmat_inv);
|
||||
td_ext->rot = nullptr;
|
||||
td_ext->rotAxis = nullptr;
|
||||
td_ext->rotAngle = nullptr;
|
||||
td_ext->quat = ss.pivot_rot;
|
||||
copy_m4_m4(td_ext->obmat, ob.object_to_world().ptr());
|
||||
copy_m3_m3(td_ext->l_smtx, obmat_inv);
|
||||
copy_m3_m4(td_ext->r_mtx, ob.object_to_world().ptr());
|
||||
copy_m3_m3(td_ext->r_smtx, obmat_inv);
|
||||
|
||||
copy_qt_qt(td->ext->iquat, ss.pivot_rot);
|
||||
td->ext->rotOrder = ROT_MODE_QUAT;
|
||||
copy_qt_qt(td_ext->iquat, ss.pivot_rot);
|
||||
td_ext->rotOrder = ROT_MODE_QUAT;
|
||||
|
||||
ss.pivot_scale[0] = 1.0f;
|
||||
ss.pivot_scale[1] = 1.0f;
|
||||
ss.pivot_scale[2] = 1.0f;
|
||||
td->ext->scale = ss.pivot_scale;
|
||||
td_ext->scale = ss.pivot_scale;
|
||||
copy_v3_v3(ss.init_pivot_scale, ss.pivot_scale);
|
||||
copy_v3_v3(td->ext->iscale, ss.init_pivot_scale);
|
||||
copy_v3_v3(td_ext->iscale, ss.init_pivot_scale);
|
||||
|
||||
copy_m3_m3(td->smtx, obmat_inv);
|
||||
copy_m3_m4(td->mtx, ob.object_to_world().ptr());
|
||||
|
||||
@@ -213,7 +213,6 @@ static TransData *SeqToTransData(Scene *scene,
|
||||
memset(td->axismtx, 0, sizeof(td->axismtx));
|
||||
td->axismtx[2][2] = 1.0f;
|
||||
|
||||
td->ext = nullptr;
|
||||
td->val = nullptr;
|
||||
|
||||
td->flag |= TD_SELECTED;
|
||||
|
||||
@@ -121,7 +121,6 @@ static TransData *SeqToTransData(
|
||||
store_transform_properties(scene, strip, origin, td);
|
||||
}
|
||||
|
||||
td->ext = nullptr;
|
||||
td->flag |= TD_SELECTED;
|
||||
td->dist = 0.0;
|
||||
|
||||
|
||||
@@ -59,7 +59,6 @@ static TransData *SeqToTransData(const Scene *scene,
|
||||
tdseq->key_index = seq::retiming_key_index_get(strip, key);
|
||||
|
||||
td->extra = static_cast<void *>(tdseq);
|
||||
td->ext = nullptr;
|
||||
td->flag |= TD_SELECTED;
|
||||
td->dist = 0.0;
|
||||
|
||||
|
||||
@@ -145,7 +145,6 @@ static void markerToTransDataInit(TransformInitContext *init_context,
|
||||
memset(td->axismtx, 0, sizeof(td->axismtx));
|
||||
td->axismtx[2][2] = 1.0f;
|
||||
|
||||
td->ext = nullptr;
|
||||
td->val = nullptr;
|
||||
|
||||
td->flag |= TD_SELECTED;
|
||||
@@ -268,7 +267,6 @@ static void planeMarkerToTransDataInit(TransformInitContext *init_context,
|
||||
memset(td->axismtx, 0, sizeof(td->axismtx));
|
||||
td->axismtx[2][2] = 1.0f;
|
||||
|
||||
td->ext = nullptr;
|
||||
td->val = nullptr;
|
||||
|
||||
td->flag |= TD_SELECTED;
|
||||
|
||||
@@ -77,7 +77,6 @@ static void markerToTransCurveDataInit(TransData *td,
|
||||
memset(td->axismtx, 0, sizeof(td->axismtx));
|
||||
td->axismtx[2][2] = 1.0f;
|
||||
|
||||
td->ext = nullptr;
|
||||
td->val = nullptr;
|
||||
|
||||
td->flag |= TD_SELECTED;
|
||||
|
||||
@@ -824,24 +824,6 @@ void postTrans(bContext *C, TransInfo *t)
|
||||
}
|
||||
}
|
||||
|
||||
void applyTransObjects(TransInfo *t)
|
||||
{
|
||||
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
|
||||
|
||||
TransData *td;
|
||||
|
||||
for (td = tc->data; td < tc->data + tc->data_len; td++) {
|
||||
copy_v3_v3(td->iloc, td->loc);
|
||||
if (td->ext->rot) {
|
||||
copy_v3_v3(td->ext->irot, td->ext->rot);
|
||||
}
|
||||
if (td->ext->scale) {
|
||||
copy_v3_v3(td->ext->iscale, td->ext->scale);
|
||||
}
|
||||
}
|
||||
recalc_data(t);
|
||||
}
|
||||
|
||||
static void transdata_restore_basic(TransDataBasic *td_basic)
|
||||
{
|
||||
if (td_basic->loc) {
|
||||
@@ -860,25 +842,6 @@ static void restoreElement(TransData *td)
|
||||
{
|
||||
transdata_restore_basic((TransDataBasic *)td);
|
||||
|
||||
if (td->ext && (td->flag & TD_NO_EXT) == 0) {
|
||||
if (td->ext->rot) {
|
||||
copy_v3_v3(td->ext->rot, td->ext->irot);
|
||||
}
|
||||
if (td->ext->rotAngle) {
|
||||
*td->ext->rotAngle = td->ext->irotAngle;
|
||||
}
|
||||
if (td->ext->rotAxis) {
|
||||
copy_v3_v3(td->ext->rotAxis, td->ext->irotAxis);
|
||||
}
|
||||
/* XXX, `drotAngle` & `drotAxis` not used yet. */
|
||||
if (td->ext->scale) {
|
||||
copy_v3_v3(td->ext->scale, td->ext->iscale);
|
||||
}
|
||||
if (td->ext->quat) {
|
||||
copy_qt_qt(td->ext->quat, td->ext->iquat);
|
||||
}
|
||||
}
|
||||
|
||||
if (td->flag & TD_BEZTRIPLE) {
|
||||
*(td->hdata->h1) = td->hdata->ih1;
|
||||
*(td->hdata->h2) = td->hdata->ih2;
|
||||
@@ -901,6 +864,32 @@ void restoreTransObjects(TransInfo *t)
|
||||
transdata_restore_basic((TransDataBasic *)tdm);
|
||||
}
|
||||
|
||||
if (tc->data_ext) {
|
||||
for (int i = 0; i < tc->data_len; i++) {
|
||||
if (tc->data[i].flag & TD_NO_EXT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TransDataExtension *td_ext = &tc->data_ext[i];
|
||||
if (td_ext->rot) {
|
||||
copy_v3_v3(td_ext->rot, td_ext->irot);
|
||||
}
|
||||
if (td_ext->rotAngle) {
|
||||
*td_ext->rotAngle = td_ext->irotAngle;
|
||||
}
|
||||
if (td_ext->rotAxis) {
|
||||
copy_v3_v3(td_ext->rotAxis, td_ext->irotAxis);
|
||||
}
|
||||
/* XXX, `drotAngle` & `drotAxis` not used yet. */
|
||||
if (td_ext->scale) {
|
||||
copy_v3_v3(td_ext->scale, td_ext->iscale);
|
||||
}
|
||||
if (td_ext->quat) {
|
||||
copy_qt_qt(td_ext->quat, td_ext->iquat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (td2d = tc->data_2d; tc->data_2d && td2d < tc->data_2d + tc->data_len; td2d++) {
|
||||
if (td2d->h1) {
|
||||
td2d->h1[0] = td2d->ih1[0];
|
||||
@@ -1392,7 +1381,10 @@ void calculatePropRatio(TransInfo *t)
|
||||
}
|
||||
}
|
||||
|
||||
void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot)
|
||||
void transform_data_ext_rotate(TransData *td,
|
||||
TransDataExtension *td_ext,
|
||||
float mat[3][3],
|
||||
bool use_drot)
|
||||
{
|
||||
float totmat[3][3];
|
||||
float smat[3][3];
|
||||
@@ -1407,30 +1399,30 @@ void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot)
|
||||
|
||||
/* Logic from #BKE_object_rot_to_mat3. */
|
||||
if (use_drot) {
|
||||
if (td->ext->rotOrder > 0) {
|
||||
eulO_to_mat3(dmat, td->ext->drot, td->ext->rotOrder);
|
||||
if (td_ext->rotOrder > 0) {
|
||||
eulO_to_mat3(dmat, td_ext->drot, td_ext->rotOrder);
|
||||
}
|
||||
else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
|
||||
else if (td_ext->rotOrder == ROT_MODE_AXISANGLE) {
|
||||
#if 0
|
||||
axis_angle_to_mat3(dmat, td->ext->drotAxis, td->ext->drotAngle);
|
||||
axis_angle_to_mat3(dmat, td_ext->drotAxis, td_ext->drotAngle);
|
||||
#else
|
||||
unit_m3(dmat);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
float tquat[4];
|
||||
normalize_qt_qt(tquat, td->ext->dquat);
|
||||
normalize_qt_qt(tquat, td_ext->dquat);
|
||||
quat_to_mat3(dmat, tquat);
|
||||
}
|
||||
|
||||
invert_m3_m3(dmat_inv, dmat);
|
||||
}
|
||||
|
||||
if (td->ext->rotOrder == ROT_MODE_QUAT) {
|
||||
if (td_ext->rotOrder == ROT_MODE_QUAT) {
|
||||
float quat[4];
|
||||
|
||||
/* Calculate the total rotation. */
|
||||
quat_to_mat3(obmat, td->ext->iquat);
|
||||
quat_to_mat3(obmat, td_ext->iquat);
|
||||
if (use_drot) {
|
||||
mul_m3_m3m3(obmat, dmat, obmat);
|
||||
}
|
||||
@@ -1445,13 +1437,13 @@ void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot)
|
||||
mat3_to_quat(quat, fmat);
|
||||
|
||||
/* Apply. */
|
||||
copy_qt_qt(td->ext->quat, quat);
|
||||
copy_qt_qt(td_ext->quat, quat);
|
||||
}
|
||||
else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
|
||||
else if (td_ext->rotOrder == ROT_MODE_AXISANGLE) {
|
||||
float axis[3], angle;
|
||||
|
||||
/* Calculate the total rotation. */
|
||||
axis_angle_to_mat3(obmat, td->ext->irotAxis, td->ext->irotAngle);
|
||||
axis_angle_to_mat3(obmat, td_ext->irotAxis, td_ext->irotAngle);
|
||||
if (use_drot) {
|
||||
mul_m3_m3m3(obmat, dmat, obmat);
|
||||
}
|
||||
@@ -1466,14 +1458,14 @@ void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot)
|
||||
mat3_to_axis_angle(axis, &angle, fmat);
|
||||
|
||||
/* Apply. */
|
||||
copy_v3_v3(td->ext->rotAxis, axis);
|
||||
*td->ext->rotAngle = angle;
|
||||
copy_v3_v3(td_ext->rotAxis, axis);
|
||||
*td_ext->rotAngle = angle;
|
||||
}
|
||||
else {
|
||||
float eul[3];
|
||||
|
||||
/* Calculate the total rotation. */
|
||||
eulO_to_mat3(obmat, td->ext->irot, td->ext->rotOrder);
|
||||
eulO_to_mat3(obmat, td_ext->irot, td_ext->rotOrder);
|
||||
if (use_drot) {
|
||||
mul_m3_m3m3(obmat, dmat, obmat);
|
||||
}
|
||||
@@ -1485,10 +1477,10 @@ void transform_data_ext_rotate(TransData *td, float mat[3][3], bool use_drot)
|
||||
mul_m3_m3m3(fmat, dmat_inv, fmat);
|
||||
}
|
||||
|
||||
mat3_to_compatible_eulO(eul, td->ext->rot, td->ext->rotOrder, fmat);
|
||||
mat3_to_compatible_eulO(eul, td_ext->rot, td_ext->rotOrder, fmat);
|
||||
|
||||
/* Apply. */
|
||||
copy_v3_v3(td->ext->rot, eul);
|
||||
copy_v3_v3(td_ext->rot, eul);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -347,35 +347,36 @@ void constraintTransLim(const TransInfo *t, const TransDataContainer *tc, TransD
|
||||
}
|
||||
}
|
||||
|
||||
static void constraintob_from_transdata(bConstraintOb *cob, TransData *td)
|
||||
static void constraintob_from_transdata(bConstraintOb *cob, TransDataExtension *td_ext)
|
||||
{
|
||||
/* Make a temporary bConstraintOb for use by limit constraints
|
||||
* - they only care that cob->matrix is correctly set ;-)
|
||||
* - current space should be local
|
||||
*/
|
||||
memset(cob, 0, sizeof(bConstraintOb));
|
||||
if (td->ext) {
|
||||
if (td->ext->rotOrder == ROT_MODE_QUAT) {
|
||||
/* Quaternion. */
|
||||
/* Objects and bones do normalization first too, otherwise
|
||||
* we don't necessarily end up with a rotation matrix, and
|
||||
* then conversion back to quat gives a different result. */
|
||||
float quat[4];
|
||||
normalize_qt_qt(quat, td->ext->quat);
|
||||
quat_to_mat4(cob->matrix, quat);
|
||||
}
|
||||
else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
|
||||
/* Axis angle. */
|
||||
axis_angle_to_mat4(cob->matrix, td->ext->rotAxis, *td->ext->rotAngle);
|
||||
}
|
||||
else {
|
||||
/* Eulers. */
|
||||
eulO_to_mat4(cob->matrix, td->ext->rot, td->ext->rotOrder);
|
||||
}
|
||||
if (!td_ext) {
|
||||
return;
|
||||
}
|
||||
if (td_ext->rotOrder == ROT_MODE_QUAT) {
|
||||
/* Quaternion. */
|
||||
/* Objects and bones do normalization first too, otherwise
|
||||
* we don't necessarily end up with a rotation matrix, and
|
||||
* then conversion back to quat gives a different result. */
|
||||
float quat[4];
|
||||
normalize_qt_qt(quat, td_ext->quat);
|
||||
quat_to_mat4(cob->matrix, quat);
|
||||
}
|
||||
else if (td_ext->rotOrder == ROT_MODE_AXISANGLE) {
|
||||
/* Axis angle. */
|
||||
axis_angle_to_mat4(cob->matrix, td_ext->rotAxis, *td_ext->rotAngle);
|
||||
}
|
||||
else {
|
||||
/* Eulers. */
|
||||
eulO_to_mat4(cob->matrix, td_ext->rot, td_ext->rotOrder);
|
||||
}
|
||||
}
|
||||
|
||||
static void constraintRotLim(const TransInfo * /*t*/, TransData *td)
|
||||
static void constraintRotLim(const TransInfo * /*t*/, TransData *td, TransDataExtension *td_ext)
|
||||
{
|
||||
if (td->con) {
|
||||
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_ROTLIMIT);
|
||||
@@ -409,7 +410,7 @@ static void constraintRotLim(const TransInfo * /*t*/, TransData *td)
|
||||
|
||||
/* Only do conversion if necessary, to preserve quaternion and euler rotations. */
|
||||
if (do_limit == false) {
|
||||
constraintob_from_transdata(&cob, td);
|
||||
constraintob_from_transdata(&cob, td_ext);
|
||||
do_limit = true;
|
||||
}
|
||||
|
||||
@@ -432,117 +433,126 @@ static void constraintRotLim(const TransInfo * /*t*/, TransData *td)
|
||||
|
||||
if (do_limit) {
|
||||
/* Copy results from `cob->matrix`. */
|
||||
if (td->ext->rotOrder == ROT_MODE_QUAT) {
|
||||
if (td_ext->rotOrder == ROT_MODE_QUAT) {
|
||||
/* Quaternion. */
|
||||
mat4_to_quat(td->ext->quat, cob.matrix);
|
||||
mat4_to_quat(td_ext->quat, cob.matrix);
|
||||
}
|
||||
else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
|
||||
else if (td_ext->rotOrder == ROT_MODE_AXISANGLE) {
|
||||
/* Axis angle. */
|
||||
mat4_to_axis_angle(td->ext->rotAxis, td->ext->rotAngle, cob.matrix);
|
||||
mat4_to_axis_angle(td_ext->rotAxis, td_ext->rotAngle, cob.matrix);
|
||||
}
|
||||
else {
|
||||
/* Eulers. */
|
||||
mat4_to_eulO(td->ext->rot, td->ext->rotOrder, cob.matrix);
|
||||
mat4_to_eulO(td_ext->rot, td_ext->rotOrder, cob.matrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void constraintScaleLim(const TransInfo *t, const TransDataContainer *tc, TransData *td)
|
||||
void constraintScaleLim(const TransInfo *t, const TransDataContainer *tc, int td_index)
|
||||
{
|
||||
if (td->con && td->ext) {
|
||||
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_SIZELIMIT);
|
||||
bConstraintOb cob = {nullptr};
|
||||
bConstraint *con;
|
||||
float scale_sign[3], scale_abs[3];
|
||||
int i;
|
||||
|
||||
/* Make a temporary bConstraintOb for using these limit constraints
|
||||
* - they only care that cob->matrix is correctly set ;-)
|
||||
* - current space should be local
|
||||
*/
|
||||
if ((td->flag & TD_SINGLE_SCALE) && !(t->con.mode & CON_APPLY)) {
|
||||
/* Scale val and reset the "scale". */
|
||||
return; /* TODO: fix this case. */
|
||||
}
|
||||
|
||||
/* Reset val if SINGLESIZE but using a constraint. */
|
||||
if (td->flag & TD_SINGLE_SCALE) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Separate out sign to apply back later. */
|
||||
for (i = 0; i < 3; i++) {
|
||||
scale_sign[i] = signf(td->ext->scale[i]);
|
||||
scale_abs[i] = fabsf(td->ext->scale[i]);
|
||||
}
|
||||
|
||||
size_to_mat4(cob.matrix, scale_abs);
|
||||
|
||||
/* Evaluate valid constraints. */
|
||||
for (con = td->con; con; con = con->next) {
|
||||
/* Only consider constraint if enabled. */
|
||||
if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) {
|
||||
continue;
|
||||
}
|
||||
if (con->enforce == 0.0f) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We're only interested in Limit-Scale constraints. */
|
||||
if (con->type == CONSTRAINT_TYPE_SIZELIMIT) {
|
||||
bSizeLimitConstraint *data = static_cast<bSizeLimitConstraint *>(con->data);
|
||||
|
||||
/* Only use it if it's tagged for this purpose. */
|
||||
if ((data->flag2 & LIMIT_TRANSFORM) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Do space conversions. */
|
||||
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
|
||||
/* Just multiply by `td->mtx` (this should be ok). */
|
||||
mul_m4_m3m4(cob.matrix, td->mtx, cob.matrix);
|
||||
}
|
||||
else if (con->ownspace == CONSTRAINT_SPACE_POSE) {
|
||||
/* Bone space without considering object transformations. */
|
||||
mul_m4_m3m4(cob.matrix, td->mtx, cob.matrix);
|
||||
mul_m4_m3m4(cob.matrix, tc->imat3, cob.matrix);
|
||||
}
|
||||
else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
|
||||
/* Skip... incompatible `spacetype`. */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Do constraint. */
|
||||
cti->evaluate_constraint(con, &cob, nullptr);
|
||||
|
||||
/* Convert spaces again. */
|
||||
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
|
||||
/* Just multiply by `td->smtx` (this should be ok). */
|
||||
mul_m4_m3m4(cob.matrix, td->smtx, cob.matrix);
|
||||
}
|
||||
else if (con->ownspace == CONSTRAINT_SPACE_POSE) {
|
||||
mul_m4_m3m4(cob.matrix, tc->mat3, cob.matrix);
|
||||
mul_m4_m3m4(cob.matrix, td->smtx, cob.matrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy results from `cob->matrix`. */
|
||||
if ((td->flag & TD_SINGLE_SCALE) && !(t->con.mode & CON_APPLY)) {
|
||||
/* Scale val and reset the "scale". */
|
||||
return; /* TODO: fix this case. */
|
||||
}
|
||||
|
||||
/* Reset val if SINGLESIZE but using a constraint. */
|
||||
if (td->flag & TD_SINGLE_SCALE) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Extract scale from matrix and apply back sign. */
|
||||
mat4_to_size(td->ext->scale, cob.matrix);
|
||||
mul_v3_v3(td->ext->scale, scale_sign);
|
||||
if (!tc->data_ext) {
|
||||
return;
|
||||
}
|
||||
|
||||
TransData *td = &tc->data[td_index];
|
||||
if (!td->con) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Make a temporary bConstraintOb for using these limit constraints
|
||||
* - they only care that cob->matrix is correctly set ;-)
|
||||
* - current space should be local
|
||||
*/
|
||||
if ((td->flag & TD_SINGLE_SCALE) && !(t->con.mode & CON_APPLY)) {
|
||||
/* Scale val and reset the "scale". */
|
||||
return; /* TODO: fix this case. */
|
||||
}
|
||||
|
||||
/* Reset val if SINGLESIZE but using a constraint. */
|
||||
if (td->flag & TD_SINGLE_SCALE) {
|
||||
return;
|
||||
}
|
||||
|
||||
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(CONSTRAINT_TYPE_SIZELIMIT);
|
||||
bConstraintOb cob = {nullptr};
|
||||
bConstraint *con;
|
||||
float scale_sign[3], scale_abs[3];
|
||||
int i;
|
||||
|
||||
TransDataExtension *td_ext = &tc->data_ext[td_index];
|
||||
|
||||
/* Separate out sign to apply back later. */
|
||||
for (i = 0; i < 3; i++) {
|
||||
scale_sign[i] = signf(td_ext->scale[i]);
|
||||
scale_abs[i] = fabsf(td_ext->scale[i]);
|
||||
}
|
||||
|
||||
size_to_mat4(cob.matrix, scale_abs);
|
||||
|
||||
/* Evaluate valid constraints. */
|
||||
for (con = td->con; con; con = con->next) {
|
||||
/* Only consider constraint if enabled. */
|
||||
if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) {
|
||||
continue;
|
||||
}
|
||||
if (con->enforce == 0.0f) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We're only interested in Limit-Scale constraints. */
|
||||
if (con->type == CONSTRAINT_TYPE_SIZELIMIT) {
|
||||
bSizeLimitConstraint *data = static_cast<bSizeLimitConstraint *>(con->data);
|
||||
|
||||
/* Only use it if it's tagged for this purpose. */
|
||||
if ((data->flag2 & LIMIT_TRANSFORM) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Do space conversions. */
|
||||
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
|
||||
/* Just multiply by `td->mtx` (this should be ok). */
|
||||
mul_m4_m3m4(cob.matrix, td->mtx, cob.matrix);
|
||||
}
|
||||
else if (con->ownspace == CONSTRAINT_SPACE_POSE) {
|
||||
/* Bone space without considering object transformations. */
|
||||
mul_m4_m3m4(cob.matrix, td->mtx, cob.matrix);
|
||||
mul_m4_m3m4(cob.matrix, tc->imat3, cob.matrix);
|
||||
}
|
||||
else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
|
||||
/* Skip... incompatible `spacetype`. */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Do constraint. */
|
||||
cti->evaluate_constraint(con, &cob, nullptr);
|
||||
|
||||
/* Convert spaces again. */
|
||||
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
|
||||
/* Just multiply by `td->smtx` (this should be ok). */
|
||||
mul_m4_m3m4(cob.matrix, td->smtx, cob.matrix);
|
||||
}
|
||||
else if (con->ownspace == CONSTRAINT_SPACE_POSE) {
|
||||
mul_m4_m3m4(cob.matrix, tc->mat3, cob.matrix);
|
||||
mul_m4_m3m4(cob.matrix, td->smtx, cob.matrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy results from `cob->matrix`. */
|
||||
if ((td->flag & TD_SINGLE_SCALE) && !(t->con.mode & CON_APPLY)) {
|
||||
/* Scale val and reset the "scale". */
|
||||
return; /* TODO: fix this case. */
|
||||
}
|
||||
|
||||
/* Reset val if SINGLESIZE but using a constraint. */
|
||||
if (td->flag & TD_SINGLE_SCALE) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Extract scale from matrix and apply back sign. */
|
||||
mat4_to_size(td_ext->scale, cob.matrix);
|
||||
mul_v3_v3(td_ext->scale, scale_sign);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -581,6 +591,7 @@ void headerRotation(TransInfo *t, char *str, const int str_size, float final)
|
||||
void ElementRotation_ex(const TransInfo *t,
|
||||
const TransDataContainer *tc,
|
||||
TransData *td,
|
||||
TransDataExtension *td_ext,
|
||||
const float mat[3][3],
|
||||
const float *center)
|
||||
{
|
||||
@@ -616,11 +627,11 @@ void ElementRotation_ex(const TransInfo *t,
|
||||
mul_m3_series(fmat, td->smtx, mat, td->mtx);
|
||||
mat3_to_quat(quat, fmat); /* Actual transform. */
|
||||
|
||||
if (td->ext->quat) {
|
||||
mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
|
||||
if (td_ext->quat) {
|
||||
mul_qt_qtqt(td_ext->quat, quat, td_ext->iquat);
|
||||
|
||||
/* Is there a reason not to have this here? -jahka. */
|
||||
protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
|
||||
protectedQuaternionBits(td->protectflag, td_ext->quat, td_ext->iquat);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -656,8 +667,8 @@ void ElementRotation_ex(const TransInfo *t,
|
||||
/* Do nothing. */
|
||||
}
|
||||
else if (td->flag & TD_PBONE_LOCAL_MTX_C) {
|
||||
mul_m3_v3(tc->mat3, vec); /* To Global space. */
|
||||
mul_m3_v3(td->ext->l_smtx, vec); /* To Pose space (Local Location). */
|
||||
mul_m3_v3(tc->mat3, vec); /* To Global space. */
|
||||
mul_m3_v3(td_ext->l_smtx, vec); /* To Pose space (Local Location). */
|
||||
}
|
||||
else {
|
||||
mul_m3_v3(tc->mat3, vec); /* To Global space. */
|
||||
@@ -675,58 +686,58 @@ void ElementRotation_ex(const TransInfo *t,
|
||||
/* MORE HACK: as in some cases the matrix to apply location and rot/scale is not the same,
|
||||
* and ElementRotation() might be called in Translation context (with align snapping),
|
||||
* we need to be sure to actually use the *rotation* matrix here...
|
||||
* So no other way than storing it in some dedicated members of `td->ext`! */
|
||||
* So no other way than storing it in some dedicated members of `td_ext`! */
|
||||
if ((t->flag & T_V3D_ALIGN) == 0) { /* Align mode doesn't rotate objects itself. */
|
||||
/* Euler or quaternion/axis-angle? */
|
||||
if (td->ext->rotOrder == ROT_MODE_QUAT) {
|
||||
mul_m3_series(fmat, td->ext->r_smtx, mat, td->ext->r_mtx);
|
||||
if (td_ext->rotOrder == ROT_MODE_QUAT) {
|
||||
mul_m3_series(fmat, td_ext->r_smtx, mat, td_ext->r_mtx);
|
||||
|
||||
mat3_to_quat(quat, fmat); /* Actual transform. */
|
||||
|
||||
mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
|
||||
mul_qt_qtqt(td_ext->quat, quat, td_ext->iquat);
|
||||
/* This function works on end result. */
|
||||
protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
|
||||
protectedQuaternionBits(td->protectflag, td_ext->quat, td_ext->iquat);
|
||||
}
|
||||
else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
|
||||
else if (td_ext->rotOrder == ROT_MODE_AXISANGLE) {
|
||||
/* Calculate effect based on quaternions. */
|
||||
float iquat[4], tquat[4];
|
||||
|
||||
axis_angle_to_quat(iquat, td->ext->irotAxis, td->ext->irotAngle);
|
||||
axis_angle_to_quat(iquat, td_ext->irotAxis, td_ext->irotAngle);
|
||||
|
||||
mul_m3_series(fmat, td->ext->r_smtx, mat, td->ext->r_mtx);
|
||||
mul_m3_series(fmat, td_ext->r_smtx, mat, td_ext->r_mtx);
|
||||
mat3_to_quat(quat, fmat); /* Actual transform. */
|
||||
mul_qt_qtqt(tquat, quat, iquat);
|
||||
|
||||
quat_to_axis_angle(td->ext->rotAxis, td->ext->rotAngle, tquat);
|
||||
quat_to_axis_angle(td_ext->rotAxis, td_ext->rotAngle, tquat);
|
||||
|
||||
/* This function works on end result. */
|
||||
protectedAxisAngleBits(td->protectflag,
|
||||
td->ext->rotAxis,
|
||||
td->ext->rotAngle,
|
||||
td->ext->irotAxis,
|
||||
td->ext->irotAngle);
|
||||
td_ext->rotAxis,
|
||||
td_ext->rotAngle,
|
||||
td_ext->irotAxis,
|
||||
td_ext->irotAngle);
|
||||
}
|
||||
else {
|
||||
float eulmat[3][3];
|
||||
|
||||
mul_m3_m3m3(totmat, mat, td->ext->r_mtx);
|
||||
mul_m3_m3m3(smat, td->ext->r_smtx, totmat);
|
||||
mul_m3_m3m3(totmat, mat, td_ext->r_mtx);
|
||||
mul_m3_m3m3(smat, td_ext->r_smtx, totmat);
|
||||
|
||||
/* Calculate the total rotation in eulers. */
|
||||
copy_v3_v3(eul, td->ext->irot);
|
||||
eulO_to_mat3(eulmat, eul, td->ext->rotOrder);
|
||||
copy_v3_v3(eul, td_ext->irot);
|
||||
eulO_to_mat3(eulmat, eul, td_ext->rotOrder);
|
||||
|
||||
/* `mat = transform`, `obmat = bone rotation`. */
|
||||
mul_m3_m3m3(fmat, smat, eulmat);
|
||||
|
||||
mat3_to_compatible_eulO(eul, td->ext->rot, td->ext->rotOrder, fmat);
|
||||
mat3_to_compatible_eulO(eul, td_ext->rot, td_ext->rotOrder, fmat);
|
||||
|
||||
/* And apply (to end result only). */
|
||||
protectedRotateBits(td->protectflag, eul, td->ext->irot);
|
||||
copy_v3_v3(td->ext->rot, eul);
|
||||
protectedRotateBits(td->protectflag, eul, td_ext->irot);
|
||||
copy_v3_v3(td_ext->rot, eul);
|
||||
}
|
||||
|
||||
constraintRotLim(t, td);
|
||||
constraintRotLim(t, td, td_ext);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -749,51 +760,51 @@ void ElementRotation_ex(const TransInfo *t,
|
||||
/* Rotation. */
|
||||
if ((t->flag & T_V3D_ALIGN) == 0) { /* Align mode doesn't rotate objects itself. */
|
||||
/* Euler or quaternion? */
|
||||
if ((td->ext->rotOrder == ROT_MODE_QUAT) || (td->flag & TD_USEQUAT)) {
|
||||
if ((td_ext->rotOrder == ROT_MODE_QUAT) || (td->flag & TD_USEQUAT)) {
|
||||
/* Can be called for texture space translate for example, then opt out. */
|
||||
if (td->ext->quat) {
|
||||
if (td_ext->quat) {
|
||||
mul_m3_series(fmat, td->smtx, mat, td->mtx);
|
||||
|
||||
if (!is_zero_v3(td->ext->dquat)) {
|
||||
if (!is_zero_v3(td_ext->dquat)) {
|
||||
/* Correct for delta quat. */
|
||||
float tmp_mat[3][3];
|
||||
quat_to_mat3(tmp_mat, td->ext->dquat);
|
||||
quat_to_mat3(tmp_mat, td_ext->dquat);
|
||||
mul_m3_m3m3(fmat, fmat, tmp_mat);
|
||||
}
|
||||
|
||||
mat3_to_quat(quat, fmat); /* Actual transform. */
|
||||
|
||||
if (!is_zero_v4(td->ext->dquat)) {
|
||||
if (!is_zero_v4(td_ext->dquat)) {
|
||||
/* Correct back for delta quaternion. */
|
||||
float idquat[4];
|
||||
invert_qt_qt_normalized(idquat, td->ext->dquat);
|
||||
invert_qt_qt_normalized(idquat, td_ext->dquat);
|
||||
mul_qt_qtqt(quat, idquat, quat);
|
||||
}
|
||||
|
||||
mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
|
||||
mul_qt_qtqt(td_ext->quat, quat, td_ext->iquat);
|
||||
|
||||
/* This function works on end result. */
|
||||
protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
|
||||
protectedQuaternionBits(td->protectflag, td_ext->quat, td_ext->iquat);
|
||||
}
|
||||
}
|
||||
else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
|
||||
else if (td_ext->rotOrder == ROT_MODE_AXISANGLE) {
|
||||
/* Calculate effect based on quaternions. */
|
||||
float iquat[4], tquat[4];
|
||||
|
||||
axis_angle_to_quat(iquat, td->ext->irotAxis, td->ext->irotAngle);
|
||||
axis_angle_to_quat(iquat, td_ext->irotAxis, td_ext->irotAngle);
|
||||
|
||||
mul_m3_series(fmat, td->smtx, mat, td->mtx);
|
||||
mat3_to_quat(quat, fmat); /* Actual transform. */
|
||||
mul_qt_qtqt(tquat, quat, iquat);
|
||||
|
||||
quat_to_axis_angle(td->ext->rotAxis, td->ext->rotAngle, tquat);
|
||||
quat_to_axis_angle(td_ext->rotAxis, td_ext->rotAngle, tquat);
|
||||
|
||||
/* This function works on end result. */
|
||||
protectedAxisAngleBits(td->protectflag,
|
||||
td->ext->rotAxis,
|
||||
td->ext->rotAngle,
|
||||
td->ext->irotAxis,
|
||||
td->ext->irotAngle);
|
||||
td_ext->rotAxis,
|
||||
td_ext->rotAngle,
|
||||
td_ext->irotAxis,
|
||||
td_ext->irotAngle);
|
||||
}
|
||||
else {
|
||||
/* Calculate the total rotation in eulers. */
|
||||
@@ -802,29 +813,29 @@ void ElementRotation_ex(const TransInfo *t,
|
||||
mul_m3_m3m3(totmat, mat, td->mtx);
|
||||
mul_m3_m3m3(smat, td->smtx, totmat);
|
||||
|
||||
if (!is_zero_v3(td->ext->drot)) {
|
||||
if (!is_zero_v3(td_ext->drot)) {
|
||||
/* Correct for delta rot. */
|
||||
add_eul_euleul(eul, td->ext->irot, td->ext->drot, td->ext->rotOrder);
|
||||
add_eul_euleul(eul, td_ext->irot, td_ext->drot, td_ext->rotOrder);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(eul, td->ext->irot);
|
||||
copy_v3_v3(eul, td_ext->irot);
|
||||
}
|
||||
|
||||
eulO_to_mat3(obmat, eul, td->ext->rotOrder);
|
||||
eulO_to_mat3(obmat, eul, td_ext->rotOrder);
|
||||
mul_m3_m3m3(fmat, smat, obmat);
|
||||
mat3_to_compatible_eulO(eul, td->ext->rot, td->ext->rotOrder, fmat);
|
||||
mat3_to_compatible_eulO(eul, td_ext->rot, td_ext->rotOrder, fmat);
|
||||
|
||||
if (!is_zero_v3(td->ext->drot)) {
|
||||
if (!is_zero_v3(td_ext->drot)) {
|
||||
/* Correct back for delta rot. */
|
||||
sub_eul_euleul(eul, eul, td->ext->drot, td->ext->rotOrder);
|
||||
sub_eul_euleul(eul, eul, td_ext->drot, td_ext->rotOrder);
|
||||
}
|
||||
|
||||
/* And apply. */
|
||||
protectedRotateBits(td->protectflag, eul, td->ext->irot);
|
||||
copy_v3_v3(td->ext->rot, eul);
|
||||
protectedRotateBits(td->protectflag, eul, td_ext->irot);
|
||||
copy_v3_v3(td_ext->rot, eul);
|
||||
}
|
||||
|
||||
constraintRotLim(t, td);
|
||||
constraintRotLim(t, td, td_ext);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -832,6 +843,7 @@ void ElementRotation_ex(const TransInfo *t,
|
||||
void ElementRotation(const TransInfo *t,
|
||||
const TransDataContainer *tc,
|
||||
TransData *td,
|
||||
TransDataExtension *td_ext,
|
||||
const float mat[3][3],
|
||||
const short around)
|
||||
{
|
||||
@@ -845,7 +857,7 @@ void ElementRotation(const TransInfo *t,
|
||||
center = tc->center_local;
|
||||
}
|
||||
|
||||
ElementRotation_ex(t, tc, td, mat, center);
|
||||
ElementRotation_ex(t, tc, td, td_ext, mat, center);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -951,9 +963,11 @@ static void TransMat3ToSize(const float mat[3][3], const float smat[3][3], float
|
||||
|
||||
void ElementResize(const TransInfo *t,
|
||||
const TransDataContainer *tc,
|
||||
TransData *td,
|
||||
int td_index,
|
||||
const float mat[3][3])
|
||||
{
|
||||
TransData *td = &tc->data[td_index];
|
||||
|
||||
float tmat[3][3], smat[3][3], center[3];
|
||||
float vec[3];
|
||||
|
||||
@@ -985,51 +999,55 @@ void ElementResize(const TransInfo *t,
|
||||
copy_v3_v3(center, tc->center_local);
|
||||
}
|
||||
|
||||
/* Size checked needed since the 3D cursor only uses rotation fields. */
|
||||
if (td->ext && td->ext->scale) {
|
||||
float fscale[3];
|
||||
if (tc->data_ext) {
|
||||
TransDataExtension *td_ext = &tc->data_ext[td_index];
|
||||
|
||||
if (ELEM(t->data_type,
|
||||
&TransConvertType_Sculpt,
|
||||
&TransConvertType_Object,
|
||||
&TransConvertType_ObjectTexSpace,
|
||||
&TransConvertType_Pose))
|
||||
{
|
||||
float ob_scale_mat[3][3];
|
||||
/* Reorient the size mat to fit the oriented object. */
|
||||
mul_m3_m3m3(ob_scale_mat, tmat, td->axismtx);
|
||||
// print_m3("ob_scale_mat", ob_scale_mat);
|
||||
TransMat3ToSize(ob_scale_mat, td->axismtx, fscale);
|
||||
// print_v3("fscale", fscale);
|
||||
}
|
||||
else {
|
||||
mat3_to_size(fscale, tmat);
|
||||
}
|
||||
/* Size checked needed since the 3D cursor only uses rotation fields. */
|
||||
if (td_ext->scale) {
|
||||
float fscale[3];
|
||||
|
||||
protectedScaleBits(td->protectflag, fscale);
|
||||
|
||||
if ((t->flag & T_V3D_ALIGN) == 0) { /* Align mode doesn't resize objects itself. */
|
||||
if ((td->flag & TD_SINGLE_SCALE) && !(t->con.mode & CON_APPLY)) {
|
||||
/* Scale val and reset scale. */
|
||||
*td->val = td->ival * (1 + (fscale[0] - 1) * td->factor);
|
||||
|
||||
td->ext->scale[0] = td->ext->iscale[0];
|
||||
td->ext->scale[1] = td->ext->iscale[1];
|
||||
td->ext->scale[2] = td->ext->iscale[2];
|
||||
if (ELEM(t->data_type,
|
||||
&TransConvertType_Sculpt,
|
||||
&TransConvertType_Object,
|
||||
&TransConvertType_ObjectTexSpace,
|
||||
&TransConvertType_Pose))
|
||||
{
|
||||
float ob_scale_mat[3][3];
|
||||
/* Reorient the size mat to fit the oriented object. */
|
||||
mul_m3_m3m3(ob_scale_mat, tmat, td->axismtx);
|
||||
// print_m3("ob_scale_mat", ob_scale_mat);
|
||||
TransMat3ToSize(ob_scale_mat, td->axismtx, fscale);
|
||||
// print_v3("fscale", fscale);
|
||||
}
|
||||
else {
|
||||
/* Reset val if #TD_SINGLE_SCALE but using a constraint. */
|
||||
if (td->flag & TD_SINGLE_SCALE) {
|
||||
*td->val = td->ival;
|
||||
}
|
||||
|
||||
td->ext->scale[0] = td->ext->iscale[0] * (1 + (fscale[0] - 1) * td->factor);
|
||||
td->ext->scale[1] = td->ext->iscale[1] * (1 + (fscale[1] - 1) * td->factor);
|
||||
td->ext->scale[2] = td->ext->iscale[2] * (1 + (fscale[2] - 1) * td->factor);
|
||||
mat3_to_size(fscale, tmat);
|
||||
}
|
||||
}
|
||||
|
||||
constraintScaleLim(t, tc, td);
|
||||
protectedScaleBits(td->protectflag, fscale);
|
||||
|
||||
if ((t->flag & T_V3D_ALIGN) == 0) { /* Align mode doesn't resize objects itself. */
|
||||
if ((td->flag & TD_SINGLE_SCALE) && !(t->con.mode & CON_APPLY)) {
|
||||
/* Scale val and reset scale. */
|
||||
*td->val = td->ival * (1 + (fscale[0] - 1) * td->factor);
|
||||
|
||||
td_ext->scale[0] = td_ext->iscale[0];
|
||||
td_ext->scale[1] = td_ext->iscale[1];
|
||||
td_ext->scale[2] = td_ext->iscale[2];
|
||||
}
|
||||
else {
|
||||
/* Reset val if #TD_SINGLE_SCALE but using a constraint. */
|
||||
if (td->flag & TD_SINGLE_SCALE) {
|
||||
*td->val = td->ival;
|
||||
}
|
||||
|
||||
td_ext->scale[0] = td_ext->iscale[0] * (1 + (fscale[0] - 1) * td->factor);
|
||||
td_ext->scale[1] = td_ext->iscale[1] * (1 + (fscale[1] - 1) * td->factor);
|
||||
td_ext->scale[2] = td_ext->iscale[2] * (1 + (fscale[2] - 1) * td->factor);
|
||||
}
|
||||
}
|
||||
|
||||
constraintScaleLim(t, tc, td_index);
|
||||
}
|
||||
}
|
||||
|
||||
/* For individual element center, Editmode need to use iloc. */
|
||||
|
||||
@@ -74,7 +74,7 @@ bool transform_mode_affect_only_locations(const TransInfo *t);
|
||||
void protectedTransBits(short protectflag, float vec[3]);
|
||||
void protectedScaleBits(short protectflag, float scale[3]);
|
||||
void constraintTransLim(const TransInfo *t, const TransDataContainer *tc, TransData *td);
|
||||
void constraintScaleLim(const TransInfo *t, const TransDataContainer *tc, TransData *td);
|
||||
void constraintScaleLim(const TransInfo *t, const TransDataContainer *tc, int td_index);
|
||||
/**
|
||||
* Used by Transform Rotation and Transform Normal Rotation.
|
||||
*/
|
||||
@@ -88,17 +88,19 @@ void headerRotation(TransInfo *t, char *str, int str_size, float final);
|
||||
void ElementRotation_ex(const TransInfo *t,
|
||||
const TransDataContainer *tc,
|
||||
TransData *td,
|
||||
TransDataExtension *td_ext,
|
||||
const float mat[3][3],
|
||||
const float *center);
|
||||
void ElementRotation(const TransInfo *t,
|
||||
const TransDataContainer *tc,
|
||||
TransData *td,
|
||||
TransDataExtension *td_ext,
|
||||
const float mat[3][3],
|
||||
short around);
|
||||
void headerResize(TransInfo *t, const float vec[3], char *str, int str_size);
|
||||
void ElementResize(const TransInfo *t,
|
||||
const TransDataContainer *tc,
|
||||
TransData *td,
|
||||
int td_index,
|
||||
const float mat[3][3]);
|
||||
void transform_mode_init(TransInfo *t, wmOperator *op, int mode);
|
||||
/**
|
||||
|
||||
@@ -56,7 +56,8 @@ static void applyAlign(TransInfo *t)
|
||||
|
||||
mul_m3_m3m3(mat, t->spacemtx, invmat);
|
||||
|
||||
ElementRotation(t, tc, td, mat, t->around);
|
||||
TransDataExtension *td_ext = tc->data_ext ? &tc->data_ext[i] : nullptr;
|
||||
ElementRotation(t, tc, td, td_ext, mat, t->around);
|
||||
}
|
||||
/* Restoring original center. */
|
||||
copy_v3_v3(tc->center_local, center);
|
||||
|
||||
@@ -82,7 +82,8 @@ static void applyBakeTime(TransInfo *t)
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
TransDataExtension *td_ext = tc->data_ext;
|
||||
for (i = 0; i < tc->data_len; i++, td++, td_ext++) {
|
||||
if (td->flag & TD_SKIP) {
|
||||
continue;
|
||||
}
|
||||
@@ -98,11 +99,11 @@ static void applyBakeTime(TransInfo *t)
|
||||
}
|
||||
|
||||
*dst = ival + time * td->factor;
|
||||
if (td->ext->scale && *dst < *td->ext->scale) {
|
||||
*dst = *td->ext->scale;
|
||||
if (td_ext->scale && *dst < *td_ext->scale) {
|
||||
*dst = *td_ext->scale;
|
||||
}
|
||||
if (td->ext->quat && *dst > *td->ext->quat) {
|
||||
*dst = *td->ext->quat;
|
||||
if (td_ext->quat && *dst > *td_ext->quat) {
|
||||
*dst = *td_ext->quat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ struct BendCustomData {
|
||||
static void transdata_elem_bend(const TransInfo *t,
|
||||
const TransDataContainer *tc,
|
||||
TransData *td,
|
||||
TransDataExtension *td_ext,
|
||||
float angle,
|
||||
const BendCustomData *bend_data,
|
||||
const float warp_sta_local[3],
|
||||
@@ -120,7 +121,7 @@ static void transdata_elem_bend(const TransInfo *t,
|
||||
|
||||
/* Rotation. */
|
||||
if ((t->flag & T_POINTS) == 0) {
|
||||
ElementRotation(t, tc, td, mat, V3D_AROUND_LOCAL_ORIGINS);
|
||||
ElementRotation(t, tc, td, td_ext, mat, V3D_AROUND_LOCAL_ORIGINS);
|
||||
}
|
||||
|
||||
/* Location. */
|
||||
@@ -248,12 +249,14 @@ static void Bend(TransInfo *t)
|
||||
threading::parallel_for(IndexRange(tc->data_len), 1024, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
TransData *td = &tc->data[i];
|
||||
TransDataExtension *td_ext = tc->data_ext ? &tc->data_ext[i] : nullptr;
|
||||
if (td->flag & TD_SKIP) {
|
||||
continue;
|
||||
}
|
||||
transdata_elem_bend(t,
|
||||
tc,
|
||||
td,
|
||||
td_ext,
|
||||
values.angle,
|
||||
bend_data,
|
||||
warp_sta_local,
|
||||
|
||||
@@ -39,11 +39,15 @@ namespace blender::ed::transform {
|
||||
* \param flip: If true, a mirror on all axis will be performed additionally (point
|
||||
* reflection).
|
||||
*/
|
||||
static void ElementMirror(TransInfo *t, TransDataContainer *tc, TransData *td, int axis, bool flip)
|
||||
static void ElementMirror(TransInfo *t, TransDataContainer *tc, int td_index, int axis, bool flip)
|
||||
{
|
||||
if ((t->flag & T_V3D_ALIGN) == 0 && td->ext) {
|
||||
TransData *td = &tc->data[td_index];
|
||||
|
||||
if ((t->flag & T_V3D_ALIGN) == 0 && tc->data_ext) {
|
||||
TransDataExtension *td_ext = &tc->data_ext[td_index];
|
||||
|
||||
/* Size checked needed since the 3D cursor only uses rotation fields. */
|
||||
if (td->ext->scale) {
|
||||
if (td_ext->scale) {
|
||||
float fscale[] = {1.0, 1.0, 1.0};
|
||||
|
||||
if (axis >= 0) {
|
||||
@@ -55,9 +59,9 @@ static void ElementMirror(TransInfo *t, TransDataContainer *tc, TransData *td, i
|
||||
|
||||
protectedScaleBits(td->protectflag, fscale);
|
||||
|
||||
mul_v3_v3v3(td->ext->scale, td->ext->iscale, fscale);
|
||||
mul_v3_v3v3(td_ext->scale, td_ext->iscale, fscale);
|
||||
|
||||
constraintScaleLim(t, tc, td);
|
||||
constraintScaleLim(t, tc, td_index);
|
||||
}
|
||||
|
||||
float rmat[3][3];
|
||||
@@ -74,18 +78,18 @@ static void ElementMirror(TransInfo *t, TransDataContainer *tc, TransData *td, i
|
||||
mul_m3_m3m3(rmat, rmat, imat);
|
||||
mul_m3_m3m3(rmat, t->spacemtx, rmat);
|
||||
|
||||
ElementRotation_ex(t, tc, td, rmat, td->center);
|
||||
ElementRotation_ex(t, tc, td, td_ext, rmat, td->center);
|
||||
|
||||
if (td->ext->rotAngle) {
|
||||
*td->ext->rotAngle = -td->ext->irotAngle;
|
||||
if (td_ext->rotAngle) {
|
||||
*td_ext->rotAngle = -td_ext->irotAngle;
|
||||
}
|
||||
}
|
||||
else {
|
||||
unit_m3(rmat);
|
||||
ElementRotation_ex(t, tc, td, rmat, td->center);
|
||||
ElementRotation_ex(t, tc, td, td_ext, rmat, td->center);
|
||||
|
||||
if (td->ext->rotAngle) {
|
||||
*td->ext->rotAngle = td->ext->irotAngle;
|
||||
if (td_ext->rotAngle) {
|
||||
*td_ext->rotAngle = td_ext->irotAngle;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -196,7 +200,7 @@ static void applyMirror(TransInfo *t)
|
||||
continue;
|
||||
}
|
||||
|
||||
ElementMirror(t, tc, td, special_axis, bitmap_len >= 2);
|
||||
ElementMirror(t, tc, i, special_axis, bitmap_len >= 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,7 +220,7 @@ static void applyMirror(TransInfo *t)
|
||||
continue;
|
||||
}
|
||||
|
||||
ElementMirror(t, tc, td, -1, false);
|
||||
ElementMirror(t, tc, i, -1, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -220,7 +220,7 @@ static void applyResize(TransInfo *t)
|
||||
if (td->flag & TD_SKIP) {
|
||||
continue;
|
||||
}
|
||||
ElementResize(t, tc, td, mat);
|
||||
ElementResize(t, tc, i, mat);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -234,9 +234,8 @@ static void applyResize(TransInfo *t)
|
||||
}
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
ElementResize(t, tc, td, mat);
|
||||
for (i = 0; i < tc->data_len; i++) {
|
||||
ElementResize(t, tc, i, mat);
|
||||
}
|
||||
|
||||
/* Not ideal, see #clipUVData code-comment. */
|
||||
|
||||
@@ -73,6 +73,7 @@ static void rmat_cache_update(RotateMatrixCache *rmc, const float axis[3], const
|
||||
static void transdata_elem_rotate(const TransInfo *t,
|
||||
const TransDataContainer *tc,
|
||||
TransData *td,
|
||||
TransDataExtension *td_ext,
|
||||
const float axis[3],
|
||||
const float angle,
|
||||
const float angle_step,
|
||||
@@ -106,13 +107,13 @@ static void transdata_elem_rotate(const TransInfo *t,
|
||||
* Otherwise, just assume it's useless (e.g. in case of mesh/UV/etc. editing).
|
||||
* Also need to be in Euler rotation mode, the others never allow more than one turn anyway.
|
||||
*/
|
||||
if (is_large_rotation && td->ext != nullptr && td->ext->rotOrder == ROT_MODE_EUL) {
|
||||
copy_v3_v3(td->ext->rot, td->ext->irot);
|
||||
if (is_large_rotation && td_ext != nullptr && td_ext->rotOrder == ROT_MODE_EUL) {
|
||||
copy_v3_v3(td_ext->rot, td_ext->irot);
|
||||
for (float angle_progress = angle_step; fabsf(angle_progress) < fabsf(angle_final);
|
||||
angle_progress += angle_step)
|
||||
{
|
||||
axis_angle_normalized_to_mat3(rmc->mat, axis_final, angle_progress);
|
||||
ElementRotation(t, tc, td, rmc->mat, t->around);
|
||||
ElementRotation(t, tc, td, td_ext, rmc->mat, t->around);
|
||||
}
|
||||
rmat_cache_reset(rmc);
|
||||
}
|
||||
@@ -122,7 +123,7 @@ static void transdata_elem_rotate(const TransInfo *t,
|
||||
|
||||
rmat_cache_update(rmc, axis_final, angle_final);
|
||||
|
||||
ElementRotation(t, tc, td, rmc->mat, t->around);
|
||||
ElementRotation(t, tc, td, td_ext, rmc->mat, t->around);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -210,10 +211,11 @@ static void applyRotationValue(TransInfo *t,
|
||||
rmat_cache_init(&rmc, angle, axis);
|
||||
for (const int i : range) {
|
||||
TransData *td = &tc->data[i];
|
||||
TransDataExtension *td_ext = tc->data_ext ? &tc->data_ext[i] : nullptr;
|
||||
if (td->flag & TD_SKIP) {
|
||||
continue;
|
||||
}
|
||||
transdata_elem_rotate(t, tc, td, axis, angle, angle_step, is_large_rotation, &rmc);
|
||||
transdata_elem_rotate(t, tc, td, td_ext, axis, angle, angle_step, is_large_rotation, &rmc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -37,12 +37,13 @@ namespace blender::ed::transform {
|
||||
static void transdata_elem_shrink_fatten(const TransInfo *t,
|
||||
const TransDataContainer * /*tc*/,
|
||||
TransData *td,
|
||||
TransDataExtension *td_ext,
|
||||
const float distance)
|
||||
{
|
||||
/* Get the final offset. */
|
||||
float tdistance = distance * td->factor;
|
||||
if (td->ext && (t->flag & T_ALT_TRANSFORM) != 0) {
|
||||
tdistance *= td->ext->iscale[0]; /* Shell factor. */
|
||||
if (td_ext && (t->flag & T_ALT_TRANSFORM) != 0) {
|
||||
tdistance *= td_ext->iscale[0]; /* Shell factor. */
|
||||
}
|
||||
|
||||
madd_v3_v3v3fl(td->loc, td->iloc, td->axismtx[2], tdistance);
|
||||
@@ -118,10 +119,11 @@ static void applyShrinkFatten(TransInfo *t)
|
||||
threading::parallel_for(IndexRange(tc->data_len), 1024, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
TransData *td = &tc->data[i];
|
||||
TransDataExtension *td_ext = tc->data_ext ? &tc->data_ext[i] : nullptr;
|
||||
if (td->flag & TD_SKIP) {
|
||||
continue;
|
||||
}
|
||||
transdata_elem_shrink_fatten(t, tc, td, distance);
|
||||
transdata_elem_shrink_fatten(t, tc, td, td_ext, distance);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ namespace blender::ed::transform {
|
||||
static void transdata_elem_trackball(const TransInfo *t,
|
||||
const TransDataContainer *tc,
|
||||
TransData *td,
|
||||
TransDataExtension *td_ext,
|
||||
const float axis[3],
|
||||
const float angle,
|
||||
const float mat_final[3][3])
|
||||
@@ -47,7 +48,7 @@ static void transdata_elem_trackball(const TransInfo *t,
|
||||
axis_angle_normalized_to_mat3(mat_buf, axis, td->factor * angle);
|
||||
mat = mat_buf;
|
||||
}
|
||||
ElementRotation(t, tc, td, mat, t->around);
|
||||
ElementRotation(t, tc, td, td_ext, mat, t->around);
|
||||
}
|
||||
|
||||
static void applyTrackballValue_calc_axis_angle(const TransInfo *t,
|
||||
@@ -74,10 +75,11 @@ static void applyTrackballValue(TransInfo *t, const float axis[3], const float a
|
||||
threading::parallel_for(IndexRange(tc->data_len), 1024, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
TransData *td = &tc->data[i];
|
||||
TransDataExtension *td_ext = tc->data_ext ? &tc->data_ext[i] : nullptr;
|
||||
if (td->flag & TD_SKIP) {
|
||||
continue;
|
||||
}
|
||||
transdata_elem_trackball(t, tc, td, axis, angle, mat_final);
|
||||
transdata_elem_trackball(t, tc, td, td_ext, axis, angle, mat_final);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ struct TranslateCustomData {
|
||||
static void transdata_elem_translate(const TransInfo *t,
|
||||
const TransDataContainer *tc,
|
||||
TransData *td,
|
||||
TransDataExtension *td_ext,
|
||||
const float3 &snap_source_local,
|
||||
const float3 &vec,
|
||||
enum eTranslateRotateMode rotate_mode)
|
||||
@@ -104,7 +105,7 @@ static void transdata_elem_translate(const TransInfo *t,
|
||||
rotation_between_vecs_to_mat3(mat, original_normal, t->tsnap.snapNormal);
|
||||
}
|
||||
|
||||
ElementRotation_ex(t, tc, td, mat, snap_source_local);
|
||||
ElementRotation_ex(t, tc, td, td_ext, mat, snap_source_local);
|
||||
|
||||
if (td->loc) {
|
||||
use_rotate_offset = true;
|
||||
@@ -436,10 +437,11 @@ static void applyTranslationValue(TransInfo *t, const float vec[3])
|
||||
threading::parallel_for(IndexRange(tc->data_len), 1024, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
TransData *td = &tc->data[i];
|
||||
TransDataExtension *td_ext = tc->data_ext ? &tc->data_ext[i] : nullptr;
|
||||
if (td->flag & TD_SKIP) {
|
||||
continue;
|
||||
}
|
||||
transdata_elem_translate(t, tc, td, snap_source_local, vec, rotate_mode);
|
||||
transdata_elem_translate(t, tc, td, td_ext, snap_source_local, vec, rotate_mode);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -374,7 +374,10 @@ eRedrawFlag handleSnapping(TransInfo *t, const wmEvent *event)
|
||||
return status;
|
||||
}
|
||||
|
||||
static bool applyFaceProject(TransInfo *t, TransDataContainer *tc, TransData *td)
|
||||
static bool applyFaceProject(TransInfo *t,
|
||||
TransDataContainer *tc,
|
||||
TransData *td,
|
||||
TransDataExtension *td_ext)
|
||||
{
|
||||
float iloc[3], loc[3], no[3];
|
||||
float mval_fl[2];
|
||||
@@ -435,7 +438,7 @@ static bool applyFaceProject(TransInfo *t, TransDataContainer *tc, TransData *td
|
||||
|
||||
rotation_between_vecs_to_mat3(mat, original_normal, no);
|
||||
|
||||
transform_data_ext_rotate(td, mat, true);
|
||||
transform_data_ext_rotate(td, td_ext, mat, true);
|
||||
|
||||
/* TODO: support constraints for rotation too? see #ElementRotation. */
|
||||
}
|
||||
@@ -512,6 +515,7 @@ void transform_snap_project_individual_apply(TransInfo *t)
|
||||
/* XXX: flickers in object mode. */
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
TransDataExtension *td_ext = tc->data_ext;
|
||||
for (int i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_SKIP) {
|
||||
continue;
|
||||
@@ -525,7 +529,10 @@ void transform_snap_project_individual_apply(TransInfo *t)
|
||||
* fall back to face nearest ray-cast does not hit. */
|
||||
bool hit = false;
|
||||
if (t->tsnap.mode & SCE_SNAP_INDIVIDUAL_PROJECT) {
|
||||
hit = applyFaceProject(t, tc, td);
|
||||
hit = applyFaceProject(t, tc, td, td_ext);
|
||||
if (td_ext) {
|
||||
td_ext++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hit && t->tsnap.mode & SCE_SNAP_INDIVIDUAL_NEAREST) {
|
||||
@@ -1490,6 +1497,7 @@ static void snap_source_closest_fn(TransInfo *t)
|
||||
|
||||
/* Use bound-box if possible. */
|
||||
if (bounds) {
|
||||
TransDataExtension *td_ext = &tc->data_ext[i];
|
||||
const std::array<float3, 8> bounds_corners = bounds::corners(*bounds);
|
||||
int j;
|
||||
|
||||
@@ -1498,7 +1506,7 @@ static void snap_source_closest_fn(TransInfo *t)
|
||||
float dist;
|
||||
|
||||
copy_v3_v3(loc, bounds_corners[j]);
|
||||
mul_m4_v3(td->ext->obmat, loc);
|
||||
mul_m4_v3(td_ext->obmat, loc);
|
||||
|
||||
dist = t->mode_info->snap_distance_fn(t, loc, t->tsnap.snap_target);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user