/** * Calculate a depth value from \a co, use with #ED_view3d_win_to_delta */ float ED_view3d_calc_zfac(const RegionView3D *rv3d, const float co[3], bool *r_flip) { float zfac = mul_project_m4_v3_zfac((float (*)[4])rv3d->persmat, co); if (r_flip) { *r_flip = (zfac < 0.0f); } /* if x,y,z is exactly the viewport offset, zfac is 0 and we don't want that * (accounting for near zero values) */ if (zfac < 1.e-6f && zfac > -1.e-6f) { zfac = 1.0f; } /* Negative zfac means x, y, z was behind the camera (in perspective). * This gives flipped directions, so revert back to ok default case. */ if (zfac < 0.0f) { zfac = -zfac; } return zfac; }
static void setNearestAxis3d(TransInfo *t) { float zfac; float mvec[3], proj[3]; float len[3]; int i; /* calculate mouse movement */ mvec[0] = (float)(t->mval[0] - t->con.imval[0]); mvec[1] = (float)(t->mval[1] - t->con.imval[1]); mvec[2] = 0.0f; /* we need to correct axis length for the current zoomlevel of view, * this to prevent projected values to be clipped behind the camera * and to overflow the short integers. * The formula used is a bit stupid, just a simplification of the subtraction * of two 2D points 30 pixels apart (that's the last factor in the formula) after * projecting them with ED_view3d_win_to_delta and then get the length of that vector. */ zfac = mul_project_m4_v3_zfac(t->persmat, t->center); zfac = len_v3(t->persinv[0]) * 2.0f / t->ar->winx * zfac * 30.0f; for (i = 0; i < 3; i++) { float axis[3], axis_2d[2]; copy_v3_v3(axis, t->con.mtx[i]); mul_v3_fl(axis, zfac); /* now we can project to get window coordinate */ add_v3_v3(axis, t->center_global); projectFloatView(t, axis, axis_2d); sub_v2_v2v2(axis, axis_2d, t->center2d); axis[2] = 0.0f; if (normalize_v3(axis) > 1e-3f) { project_v3_v3v3(proj, mvec, axis); sub_v3_v3v3(axis, mvec, proj); len[i] = normalize_v3(axis); } else { len[i] = 1e10f; } } if (len[0] <= len[1] && len[0] <= len[2]) { if (t->modifiers & MOD_CONSTRAINT_PLANE) { t->con.mode |= (CON_AXIS1 | CON_AXIS2); BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" locking %s X axis"), t->spacename); } else { t->con.mode |= CON_AXIS0; BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" along %s X axis"), t->spacename); } } else if (len[1] <= len[0] && len[1] <= len[2]) { if (t->modifiers & MOD_CONSTRAINT_PLANE) { t->con.mode |= (CON_AXIS0 | CON_AXIS2); BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" locking %s Y axis"), t->spacename); } else { t->con.mode |= CON_AXIS1; BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" along %s Y axis"), t->spacename); } } else if (len[2] <= len[1] && len[2] <= len[0]) { if (t->modifiers & MOD_CONSTRAINT_PLANE) { t->con.mode |= (CON_AXIS0 | CON_AXIS1); BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" locking %s Z axis"), t->spacename); } else { t->con.mode |= CON_AXIS2; BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" along %s Z axis"), t->spacename); } } }
float ED_view3d_pixel_size(RegionView3D *rv3d, const float co[3]) { return mul_project_m4_v3_zfac(rv3d->persmat, co) * rv3d->pixsize * U.pixelsize; }