Remove struct PreDefProject and store all immutable parameters within the new struct SnapData
In order to simplify the reading of these functions, the parameters: `snap_to`, `mval`, `ray_start`, `ray_dir`, `view_proj` and `depth_range` are now stored in the struct `SnapData`
This commit is contained in:
@@ -59,6 +59,18 @@
|
||||
|
||||
#include "transform.h"
|
||||
|
||||
typedef struct SnapData {
|
||||
short snap_to;
|
||||
float mval[2];
|
||||
float ray_origin[3];
|
||||
float ray_start[3];
|
||||
float ray_dir[3];
|
||||
float pmat[4][4]; /* perspective matrix */
|
||||
float win_half[2];/* win x and y */
|
||||
enum eViewProj view_proj;
|
||||
float depth_range[2];
|
||||
} SnapData;
|
||||
|
||||
typedef struct SnapObjectData {
|
||||
enum {
|
||||
SNAP_MESH = 1,
|
||||
@@ -232,26 +244,40 @@ typedef struct BVHTreeFromMeshType {
|
||||
char type;
|
||||
} BVHTreeFromMeshType;
|
||||
|
||||
typedef struct PreDefProject {
|
||||
float pmat[4][4]; /* perspective matrix multiplied by object matrix */
|
||||
float win_half[2];
|
||||
float dist_px_sq;
|
||||
} PreDefProject;
|
||||
|
||||
static void precalc_project(
|
||||
PreDefProject *projectdefs, const ARegion *ar,
|
||||
const float dist_px, float obmat[4][4])
|
||||
/*
|
||||
* Generates a struct with the immutable parameters that will be used on all objects.
|
||||
*
|
||||
* \param snap_to: Element to snap, Vertice, Edge or Face.
|
||||
* \param view_proj: ORTHO or PERSP.
|
||||
* Currently only works one at a time, but can eventually operate as flag.
|
||||
*
|
||||
* \param mval: Mouse coords.
|
||||
* (When NULL, ray-casting is handled without any projection matrix correction.)
|
||||
* \param ray_origin: ray_start before being moved toward the ray_normal at the distance from vew3d clip_min.
|
||||
* \param ray_start: ray_origin moved for the start clipping plane (clip_min).
|
||||
* \param ray_direction: Unit length direction of the ray.
|
||||
* \param depth_range: distances of clipe plane min and clip plane max;
|
||||
*/
|
||||
static void set_SnapData(
|
||||
SnapData *snapdata,
|
||||
const ARegion *ar, const unsigned short snap_to, const enum eViewProj view_proj,
|
||||
const float mval[2], const float ray_origin[3], const float ray_start[3],
|
||||
const float ray_direction[3], const float depth_range[2])
|
||||
{
|
||||
float (*pmat)[4] = ((RegionView3D *)ar->regiondata)->persmat;
|
||||
if (obmat) {
|
||||
mul_m4_m4m4(projectdefs->pmat, pmat, obmat);
|
||||
if (ar) {
|
||||
copy_m4_m4(snapdata->pmat, ((RegionView3D *)ar->regiondata)->persmat);
|
||||
snapdata->win_half[0] = ar->winx / 2;
|
||||
snapdata->win_half[1] = ar->winy / 2;
|
||||
}
|
||||
else {
|
||||
copy_m4_m4(projectdefs->pmat, pmat);
|
||||
if (mval) {
|
||||
copy_v2_v2(snapdata->mval, mval);
|
||||
}
|
||||
projectdefs->win_half[0] = ar->winx / 2;
|
||||
projectdefs->win_half[1] = ar->winy / 2;
|
||||
projectdefs->dist_px_sq = SQUARE(dist_px);
|
||||
snapdata->snap_to = snap_to;
|
||||
copy_v3_v3(snapdata->ray_origin, ray_origin);
|
||||
copy_v3_v3(snapdata->ray_start, ray_start);
|
||||
copy_v3_v3(snapdata->ray_dir, ray_direction);
|
||||
snapdata->view_proj = view_proj;
|
||||
copy_v2_v2(snapdata->depth_range, depth_range);
|
||||
}
|
||||
|
||||
static const float *get_vert_co(const BVHTreeFromMeshType *meshdata, const int index)
|
||||
@@ -322,14 +348,12 @@ static void get_edge_verts(
|
||||
}
|
||||
|
||||
static bool test_projected_vert_dist(
|
||||
PreDefProject *projectdefs,
|
||||
const float co[3], const enum eViewProj view_proj,
|
||||
const float mval[2], const float depth_range[2],
|
||||
float r_co[3])
|
||||
const float depth_range[2], const float mval[2], const float co[3],
|
||||
float pmat[4][4], const float win_half[2], const bool is_persp,
|
||||
float *dist_px_sq, float r_co[3])
|
||||
{
|
||||
float depth;
|
||||
float(*pmat)[4] = projectdefs->pmat;
|
||||
if (view_proj == VIEW_PROJ_PERSP) {
|
||||
if (is_persp) {
|
||||
depth = mul_project_m4_v3_zfac(pmat, co);
|
||||
if (depth < depth_range[0] || depth > depth_range[1]) {
|
||||
return false;
|
||||
@@ -341,34 +365,35 @@ static bool test_projected_vert_dist(
|
||||
(dot_m4_v3_row_y(pmat, co) + pmat[3][1]),
|
||||
};
|
||||
|
||||
if (view_proj == VIEW_PROJ_PERSP) {
|
||||
if (is_persp) {
|
||||
mul_v2_fl(co2d, 1 / depth);
|
||||
}
|
||||
|
||||
co2d[0] += 1.0f;
|
||||
co2d[1] += 1.0f;
|
||||
co2d[0] *= projectdefs->win_half[0];
|
||||
co2d[1] *= projectdefs->win_half[1];
|
||||
co2d[0] *= win_half[0];
|
||||
co2d[1] *= win_half[1];
|
||||
|
||||
const float dist_sq = len_squared_v2v2(mval, co2d);
|
||||
if (dist_sq < projectdefs->dist_px_sq) {
|
||||
if (dist_sq < *dist_px_sq) {
|
||||
copy_v3_v3(r_co, co);
|
||||
projectdefs->dist_px_sq = dist_sq;
|
||||
*dist_px_sq = dist_sq;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool test_projected_edge_dist(
|
||||
PreDefProject *projectdefs,
|
||||
const float va[3], const float vb[3], const float ray_start[3], const float ray_normal[3],
|
||||
const enum eViewProj view_proj, const float mval[2], const float depth_range[2],
|
||||
float r_co[3])
|
||||
const float depth_range[2], const float mval[2],
|
||||
float pmat[4][4], const float win_half[2], const bool is_persp,
|
||||
const float ray_start[3], const float ray_dir[3],
|
||||
const float va[3], const float vb[3],
|
||||
float *dist_px_sq, float r_co[3])
|
||||
{
|
||||
|
||||
float tmp_co[3], depth;
|
||||
dist_squared_ray_to_seg_v3(ray_start, ray_normal, va, vb, tmp_co, &depth);
|
||||
return test_projected_vert_dist(projectdefs, tmp_co, view_proj, mval, depth_range, r_co);
|
||||
dist_squared_ray_to_seg_v3(ray_start, ray_dir, va, vb, tmp_co, &depth);
|
||||
return test_projected_vert_dist(depth_range, mval, tmp_co, pmat, win_half, is_persp, dist_px_sq, r_co);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -383,11 +408,15 @@ typedef struct Object_Nearest2dPrecalc {
|
||||
float ray_direction_local[3];
|
||||
float ray_inv_dir[3];
|
||||
|
||||
PreDefProject projectdefs;
|
||||
float depth_range[2];
|
||||
float pmat[4][4]; /* perspective matrix multiplied by object matrix */
|
||||
float win_half[2];
|
||||
bool is_persp;
|
||||
float dist_px_sq;
|
||||
|
||||
float mval[2];
|
||||
bool sign[3];
|
||||
bool r_axis_closest[3];
|
||||
float depth_range[2];
|
||||
|
||||
void *userdata;
|
||||
int index;
|
||||
@@ -397,16 +426,24 @@ typedef struct Object_Nearest2dPrecalc {
|
||||
|
||||
|
||||
static void nearest2d_precalc(
|
||||
Object_Nearest2dPrecalc *neasrest_precalc, const ARegion *ar,
|
||||
Object_Nearest2dPrecalc *neasrest_precalc, SnapData *snapdata,
|
||||
const float dist_px, float obmat[4][4],
|
||||
const float ray_origin_local[3], const float ray_direction_local[3],
|
||||
const float mval[2], const float depth_range[2])
|
||||
const float ray_origin_local[3], const float ray_direction_local[3])
|
||||
{
|
||||
precalc_project(&neasrest_precalc->projectdefs, ar, dist_px, obmat);
|
||||
if (obmat) {
|
||||
mul_m4_m4m4(neasrest_precalc->pmat, snapdata->pmat, obmat);
|
||||
}
|
||||
else {
|
||||
copy_m4_m4(neasrest_precalc->pmat, snapdata->pmat);
|
||||
}
|
||||
copy_v2_v2(neasrest_precalc->win_half, snapdata->win_half);
|
||||
neasrest_precalc->dist_px_sq = SQUARE(dist_px);
|
||||
neasrest_precalc->is_persp = snapdata->view_proj == VIEW_PROJ_PERSP;
|
||||
copy_v2_v2(neasrest_precalc->depth_range, snapdata->depth_range);
|
||||
|
||||
copy_v3_v3(neasrest_precalc->ray_origin_local, ray_origin_local);
|
||||
copy_v3_v3(neasrest_precalc->ray_direction_local, ray_direction_local);
|
||||
copy_v2_v2(neasrest_precalc->mval, mval);
|
||||
copy_v2_v2(neasrest_precalc->depth_range, depth_range);
|
||||
copy_v2_v2(neasrest_precalc->mval, snapdata->mval);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
neasrest_precalc->ray_inv_dir[i] =
|
||||
@@ -456,9 +493,9 @@ static bool cb_walk_parent_snap_project(const BVHTreeAxisRange *bounds, void *us
|
||||
(local_bvmax[1] - data->ray_origin_local[1]) * data->ray_inv_dir[1],
|
||||
(local_bvmax[2] - data->ray_origin_local[2]) * data->ray_inv_dir[2],
|
||||
};
|
||||
/* va[3] and vb[3] are the coordinates of the AABB edge closest to the ray */
|
||||
/* `va` and `vb` are the coordinates of the AABB edge closest to the ray */
|
||||
float va[3], vb[3];
|
||||
/* rtmin and rtmax are the distances of the minimum and maximum ray hits on the AABB */
|
||||
/* `rtmin` and `rtmax` are the minimum and maximum distances of the ray hits on the AABB */
|
||||
float rtmin, rtmax;
|
||||
int main_axis;
|
||||
|
||||
@@ -506,10 +543,10 @@ static bool cb_walk_parent_snap_project(const BVHTreeAxisRange *bounds, void *us
|
||||
/* if rtmin < rtmax, ray intersect `AABB` */
|
||||
if (rtmin <= rtmax) {
|
||||
#ifdef IGNORE_BEHIND_RAY
|
||||
/* `if rtmax < depth_min`, the hit is behind us
|
||||
* TODO: Check if the entire AABB is behind ray
|
||||
* this will prevent unnecessary leaf testing*/
|
||||
if (rtmax < depth_range[0]) {
|
||||
/* `if rtmax < depth_min`, the hit is behind us */
|
||||
if (rtmax < data->depth_range[0]) {
|
||||
/* TODO: TODO: Check if the entire AABB is behind ray
|
||||
* this will prevent unnecessary leaf testing */
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
@@ -518,9 +555,9 @@ static bool cb_walk_parent_snap_project(const BVHTreeAxisRange *bounds, void *us
|
||||
return true;
|
||||
}
|
||||
#ifdef IGNORE_BEHIND_RAY
|
||||
/* `if rtmin < depth_min`, the hit is behing us
|
||||
* TODO: Check if the entire AABB is behind ray */
|
||||
else if (rtmin < depth_range[0]) {
|
||||
/* `if rtmin < depth_min`, the hit is behing us */
|
||||
else if (rtmin < data->depth_range[0]) {
|
||||
/* TODO: Test if the AABB is totally behind ray */
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
@@ -534,7 +571,7 @@ static bool cb_walk_parent_snap_project(const BVHTreeAxisRange *bounds, void *us
|
||||
}
|
||||
float scale = fabsf(local_bvmax[main_axis] - local_bvmin[main_axis]);
|
||||
|
||||
float (*pmat)[4] = data->projectdefs.pmat;
|
||||
float (*pmat)[4] = data->pmat;
|
||||
float depth_a = mul_project_m4_v3_zfac(pmat, va);
|
||||
float depth_b = depth_a + pmat[main_axis][3] * scale;
|
||||
|
||||
@@ -555,10 +592,10 @@ static bool cb_walk_parent_snap_project(const BVHTreeAxisRange *bounds, void *us
|
||||
vb2d[0] += 1.0f;
|
||||
vb2d[1] += 1.0f;
|
||||
|
||||
va2d[0] *= data->projectdefs.win_half[0];
|
||||
va2d[1] *= data->projectdefs.win_half[1];
|
||||
vb2d[0] *= data->projectdefs.win_half[0];
|
||||
vb2d[1] *= data->projectdefs.win_half[1];
|
||||
va2d[0] *= data->win_half[0];
|
||||
va2d[1] *= data->win_half[1];
|
||||
vb2d[0] *= data->win_half[0];
|
||||
vb2d[1] *= data->win_half[1];
|
||||
|
||||
//float dvec[2], edge[2], rdist;
|
||||
//sub_v2_v2v2(dvec, data->mval, va2d);
|
||||
@@ -587,7 +624,7 @@ static bool cb_walk_parent_snap_project(const BVHTreeAxisRange *bounds, void *us
|
||||
else {
|
||||
rdist = len_squared_v2v2(data->mval, va2d);
|
||||
}
|
||||
return rdist < data->projectdefs.dist_px_sq;
|
||||
return rdist < data->dist_px_sq;
|
||||
}
|
||||
|
||||
static bool cb_walk_leaf_snap_vert(const BVHTreeAxisRange *bounds, int index, void *userdata)
|
||||
@@ -599,12 +636,13 @@ static bool cb_walk_leaf_snap_vert(const BVHTreeAxisRange *bounds, int index, vo
|
||||
(bounds[2].min + bounds[2].max) / 2,
|
||||
};
|
||||
|
||||
/* Although this function is also used in the Othogonal view (VIEW_PROJ_ORTHO),
|
||||
* we put `eViewProj view_proj` as` VIEW_PROJ_PERSP` because it works in both cases
|
||||
* (with the disadvantage of executing unnecessary calculations) */
|
||||
if (test_projected_vert_dist(
|
||||
&neasrest_precalc->projectdefs, co, VIEW_PROJ_PERSP,
|
||||
neasrest_precalc->mval, neasrest_precalc->depth_range,
|
||||
neasrest_precalc->depth_range,
|
||||
neasrest_precalc->mval, co,
|
||||
neasrest_precalc->pmat,
|
||||
neasrest_precalc->win_half,
|
||||
neasrest_precalc->is_persp,
|
||||
&neasrest_precalc->dist_px_sq,
|
||||
neasrest_precalc->co))
|
||||
{
|
||||
copy_vert_no(neasrest_precalc->userdata, index, neasrest_precalc->no);
|
||||
@@ -620,13 +658,16 @@ static bool cb_walk_leaf_snap_edge(const BVHTreeAxisRange *UNUSED(bounds), int i
|
||||
const float *v_pair[2];
|
||||
get_edge_verts(neasrest_precalc->userdata, index, v_pair);
|
||||
|
||||
/* Although this function is also used in the Othogonal view (VIEW_PROJ_ORTHO),
|
||||
* we put `eViewProj view_proj` as` VIEW_PROJ_PERSP` because it works in both cases
|
||||
* (with the disadvantage of executing unnecessary calculations) */
|
||||
if (test_projected_edge_dist(
|
||||
&neasrest_precalc->projectdefs, v_pair[0], v_pair[1],
|
||||
neasrest_precalc->ray_origin_local, neasrest_precalc->ray_direction_local,
|
||||
VIEW_PROJ_PERSP, neasrest_precalc->mval, neasrest_precalc->depth_range,
|
||||
neasrest_precalc->depth_range,
|
||||
neasrest_precalc->mval,
|
||||
neasrest_precalc->pmat,
|
||||
neasrest_precalc->win_half,
|
||||
neasrest_precalc->is_persp,
|
||||
neasrest_precalc->ray_origin_local,
|
||||
neasrest_precalc->ray_direction_local,
|
||||
v_pair[0], v_pair[1],
|
||||
&neasrest_precalc->dist_px_sq,
|
||||
neasrest_precalc->co))
|
||||
{
|
||||
sub_v3_v3v3(neasrest_precalc->no, v_pair[0], v_pair[1]);
|
||||
@@ -649,9 +690,8 @@ static bool cb_nearest_walk_order(const BVHTreeAxisRange *UNUSED(bounds), char a
|
||||
* \{ */
|
||||
|
||||
static bool snapArmature(
|
||||
const ARegion *ar, Object *ob, bArmature *arm, float obmat[4][4],
|
||||
const short snap_to, const float origin[3], const float dir[3],
|
||||
const float mval[2], const enum eViewProj view_proj, const float depth_range[2],
|
||||
SnapData *snapdata,
|
||||
Object *ob, bArmature *arm, float obmat[4][4],
|
||||
/* read/write args */
|
||||
float *dist_px,
|
||||
/* return args */
|
||||
@@ -659,36 +699,47 @@ static bool snapArmature(
|
||||
{
|
||||
bool retval = false;
|
||||
|
||||
float ray_start_local[3], ray_normal_local[3];
|
||||
if (snap_to != SCE_SNAP_MODE_VERTEX) {
|
||||
float ray_start_local[3], ray_normal_local[3]; /* Used only in the snap to edges */
|
||||
if (snapdata->snap_to == SCE_SNAP_MODE_EDGE) {
|
||||
float imat[4][4];
|
||||
invert_m4_m4(imat, obmat);
|
||||
|
||||
copy_v3_v3(ray_start_local, origin);
|
||||
copy_v3_v3(ray_normal_local, dir);
|
||||
copy_v3_v3(ray_start_local, snapdata->ray_origin);
|
||||
copy_v3_v3(ray_normal_local, snapdata->ray_dir);
|
||||
mul_m4_v3(imat, ray_start_local);
|
||||
mul_mat3_m4_v3(imat, ray_normal_local);
|
||||
}
|
||||
else if (snapdata->snap_to != SCE_SNAP_MODE_VERTEX) { /* Currently only edge and vert */
|
||||
return retval;
|
||||
}
|
||||
|
||||
PreDefProject projectdefs;
|
||||
precalc_project(&projectdefs, ar, *dist_px, obmat);
|
||||
bool is_persp = snapdata->view_proj == VIEW_PROJ_PERSP;
|
||||
float lpmat[4][4], dist_px_sq;
|
||||
mul_m4_m4m4(lpmat, snapdata->pmat, obmat);
|
||||
dist_px_sq = SQUARE(*dist_px);
|
||||
|
||||
if (arm->edbo) {
|
||||
for (EditBone *eBone = arm->edbo->first; eBone; eBone = eBone->next) {
|
||||
if (eBone->layer & arm->layer) {
|
||||
/* skip hidden or moving (selected) bones */
|
||||
if ((eBone->flag & (BONE_HIDDEN_A | BONE_ROOTSEL | BONE_TIPSEL)) == 0) {
|
||||
switch (snap_to) {
|
||||
switch (snapdata->snap_to) {
|
||||
case SCE_SNAP_MODE_VERTEX:
|
||||
retval |= test_projected_vert_dist(
|
||||
&projectdefs, eBone->head, view_proj, mval, depth_range, r_loc);
|
||||
snapdata->depth_range, snapdata->mval, eBone->head,
|
||||
lpmat, snapdata->win_half, is_persp, &dist_px_sq,
|
||||
r_loc);
|
||||
retval |= test_projected_vert_dist(
|
||||
&projectdefs, eBone->tail, view_proj, mval, depth_range, r_loc);
|
||||
snapdata->depth_range, snapdata->mval, eBone->tail,
|
||||
lpmat, snapdata->win_half, is_persp, &dist_px_sq,
|
||||
r_loc);
|
||||
break;
|
||||
case SCE_SNAP_MODE_EDGE:
|
||||
retval |= test_projected_edge_dist(
|
||||
&projectdefs, eBone->head, eBone->tail, ray_start_local, ray_normal_local,
|
||||
view_proj, mval, depth_range, r_loc);
|
||||
snapdata->depth_range, snapdata->mval, lpmat,
|
||||
snapdata->win_half, is_persp, ray_start_local, ray_normal_local,
|
||||
eBone->head, eBone->tail,
|
||||
&dist_px_sq, r_loc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -703,24 +754,30 @@ static bool snapArmature(
|
||||
const float *head_vec = pchan->pose_head;
|
||||
const float *tail_vec = pchan->pose_tail;
|
||||
|
||||
switch (snap_to) {
|
||||
switch (snapdata->snap_to) {
|
||||
case SCE_SNAP_MODE_VERTEX:
|
||||
retval |= test_projected_vert_dist(
|
||||
&projectdefs, head_vec, view_proj, mval, depth_range, r_loc);
|
||||
snapdata->depth_range, snapdata->mval, head_vec,
|
||||
lpmat, snapdata->win_half, is_persp, &dist_px_sq,
|
||||
r_loc);
|
||||
retval |= test_projected_vert_dist(
|
||||
&projectdefs, tail_vec, view_proj, mval, depth_range, r_loc);
|
||||
snapdata->depth_range, snapdata->mval, tail_vec,
|
||||
lpmat, snapdata->win_half, is_persp, &dist_px_sq,
|
||||
r_loc);
|
||||
break;
|
||||
case SCE_SNAP_MODE_EDGE:
|
||||
retval |= test_projected_edge_dist(
|
||||
&projectdefs, head_vec, tail_vec, ray_start_local, ray_normal_local,
|
||||
view_proj, mval, depth_range, r_loc);
|
||||
snapdata->depth_range, snapdata->mval, lpmat,
|
||||
snapdata->win_half, is_persp, ray_start_local, ray_normal_local,
|
||||
head_vec, tail_vec,
|
||||
&dist_px_sq, r_loc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (retval) {
|
||||
*dist_px = sqrtf(projectdefs.dist_px_sq);
|
||||
*dist_px = sqrtf(dist_px_sq);
|
||||
mul_m4_v3(obmat, r_loc);
|
||||
return true;
|
||||
}
|
||||
@@ -728,9 +785,8 @@ static bool snapArmature(
|
||||
}
|
||||
|
||||
static bool snapCurve(
|
||||
const ARegion *ar, Object *ob, Curve *cu, float obmat[4][4],
|
||||
const short snap_to, const float mval[2], const enum eViewProj view_proj,
|
||||
const float depth_range[2],
|
||||
SnapData *snapdata,
|
||||
Object *ob, Curve *cu, float obmat[4][4],
|
||||
/* read/write args */
|
||||
float *dist_px,
|
||||
/* return args */
|
||||
@@ -739,16 +795,18 @@ static bool snapCurve(
|
||||
bool retval = false;
|
||||
|
||||
/* only vertex snapping mode (eg control points and handles) supported for now) */
|
||||
if (snap_to != SCE_SNAP_MODE_VERTEX) {
|
||||
if (snapdata->snap_to != SCE_SNAP_MODE_VERTEX) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
PreDefProject projectdefs;
|
||||
precalc_project(&projectdefs, ar, *dist_px, obmat);
|
||||
bool is_persp = snapdata->view_proj == VIEW_PROJ_PERSP;
|
||||
float lpmat[4][4], dist_px_sq;
|
||||
mul_m4_m4m4(lpmat, snapdata->pmat, obmat);
|
||||
dist_px_sq = SQUARE(*dist_px);
|
||||
|
||||
for (Nurb *nu = (ob->mode == OB_MODE_EDIT ? cu->editnurb->nurbs.first : cu->nurb.first); nu; nu = nu->next) {
|
||||
for (int u = 0; u < nu->pntsu; u++) {
|
||||
switch (snap_to) {
|
||||
switch (snapdata->snap_to) {
|
||||
case SCE_SNAP_MODE_VERTEX:
|
||||
{
|
||||
if (ob->mode == OB_MODE_EDIT) {
|
||||
@@ -758,19 +816,25 @@ static bool snapCurve(
|
||||
break;
|
||||
}
|
||||
retval |= test_projected_vert_dist(
|
||||
&projectdefs, nu->bezt[u].vec[1], view_proj, mval, depth_range, r_loc);
|
||||
snapdata->depth_range, snapdata->mval, nu->bezt[u].vec[1],
|
||||
lpmat, snapdata->win_half, is_persp, &dist_px_sq,
|
||||
r_loc);
|
||||
/* don't snap if handle is selected (moving), or if it is aligning to a moving handle */
|
||||
if (!(nu->bezt[u].f1 & SELECT) &&
|
||||
!(nu->bezt[u].h1 & HD_ALIGN && nu->bezt[u].f3 & SELECT))
|
||||
{
|
||||
retval |= test_projected_vert_dist(
|
||||
&projectdefs, nu->bezt[u].vec[0], view_proj, mval, depth_range, r_loc);
|
||||
snapdata->depth_range, snapdata->mval, nu->bezt[u].vec[0],
|
||||
lpmat, snapdata->win_half, is_persp, &dist_px_sq,
|
||||
r_loc);
|
||||
}
|
||||
if (!(nu->bezt[u].f3 & SELECT) &&
|
||||
!(nu->bezt[u].h2 & HD_ALIGN && nu->bezt[u].f1 & SELECT))
|
||||
{
|
||||
retval |= test_projected_vert_dist(
|
||||
&projectdefs, nu->bezt[u].vec[2], view_proj, mval, depth_range, r_loc);
|
||||
snapdata->depth_range, snapdata->mval, nu->bezt[u].vec[2],
|
||||
lpmat, snapdata->win_half, is_persp, &dist_px_sq,
|
||||
r_loc);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -779,7 +843,9 @@ static bool snapCurve(
|
||||
break;
|
||||
}
|
||||
retval |= test_projected_vert_dist(
|
||||
&projectdefs, nu->bp[u].vec, view_proj, mval, depth_range, r_loc);
|
||||
snapdata->depth_range, snapdata->mval, nu->bp[u].vec,
|
||||
lpmat, snapdata->win_half, is_persp, &dist_px_sq,
|
||||
r_loc);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -787,11 +853,15 @@ static bool snapCurve(
|
||||
if (nu->pntsu > 1) {
|
||||
if (nu->bezt) {
|
||||
retval |= test_projected_vert_dist(
|
||||
&projectdefs, nu->bezt[u].vec[1], view_proj, mval, depth_range, r_loc);
|
||||
snapdata->depth_range, snapdata->mval, nu->bezt[u].vec[1],
|
||||
lpmat, snapdata->win_half, is_persp, &dist_px_sq,
|
||||
r_loc);
|
||||
}
|
||||
else {
|
||||
retval |= test_projected_vert_dist(
|
||||
&projectdefs, nu->bp[u].vec, view_proj, mval, depth_range, r_loc);
|
||||
snapdata->depth_range, snapdata->mval, nu->bp[u].vec,
|
||||
lpmat, snapdata->win_half, is_persp, &dist_px_sq,
|
||||
r_loc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -803,7 +873,7 @@ static bool snapCurve(
|
||||
}
|
||||
}
|
||||
if (retval) {
|
||||
*dist_px = sqrtf(projectdefs.dist_px_sq);
|
||||
*dist_px = sqrtf(dist_px_sq);
|
||||
mul_m4_v3(obmat, r_loc);
|
||||
return true;
|
||||
}
|
||||
@@ -812,9 +882,8 @@ static bool snapCurve(
|
||||
|
||||
/* may extend later (for now just snaps to empty center) */
|
||||
static bool snapEmpty(
|
||||
const ARegion *ar, Object *ob, float obmat[4][4],
|
||||
const short snap_to, const float mval[2], const enum eViewProj view_proj,
|
||||
const float depth_range[2],
|
||||
SnapData *snapdata,
|
||||
Object *ob, float obmat[4][4],
|
||||
/* read/write args */
|
||||
float *dist_px,
|
||||
/* return args */
|
||||
@@ -827,15 +896,18 @@ static bool snapEmpty(
|
||||
}
|
||||
|
||||
/* for now only vertex supported */
|
||||
switch (snap_to) {
|
||||
switch (snapdata->snap_to) {
|
||||
case SCE_SNAP_MODE_VERTEX:
|
||||
{
|
||||
PreDefProject projectdefs;
|
||||
precalc_project(&projectdefs, ar, *dist_px, NULL);
|
||||
bool is_persp = snapdata->view_proj == VIEW_PROJ_PERSP;
|
||||
float dist_px_sq = SQUARE(*dist_px);
|
||||
float tmp_co[3];
|
||||
copy_v3_v3(tmp_co, obmat[3]);
|
||||
if (test_projected_vert_dist(&projectdefs, tmp_co, view_proj, mval, depth_range, r_loc)) {
|
||||
*dist_px = sqrtf(projectdefs.dist_px_sq);
|
||||
if (test_projected_vert_dist(
|
||||
snapdata->depth_range, snapdata->mval, tmp_co,
|
||||
snapdata->pmat, snapdata->win_half, is_persp, &dist_px_sq,
|
||||
r_loc)) {
|
||||
*dist_px = sqrtf(dist_px_sq);
|
||||
retval = true;
|
||||
}
|
||||
break;
|
||||
@@ -848,9 +920,8 @@ static bool snapEmpty(
|
||||
}
|
||||
|
||||
static bool snapCamera(
|
||||
const SnapObjectContext *sctx, Object *object, float obmat[4][4],
|
||||
const short snap_to, const float mval[2], const enum eViewProj view_proj,
|
||||
const float depth_range[2],
|
||||
const SnapObjectContext *sctx, SnapData *snapdata,
|
||||
Object *object, float obmat[4][4],
|
||||
/* read/write args */
|
||||
float *dist_px,
|
||||
/* return args */
|
||||
@@ -858,8 +929,8 @@ static bool snapCamera(
|
||||
{
|
||||
Scene *scene = sctx->scene;
|
||||
|
||||
PreDefProject projectdefs;
|
||||
precalc_project(&projectdefs, sctx->v3d_data.ar, *dist_px, NULL);
|
||||
bool is_persp = snapdata->view_proj == VIEW_PROJ_PERSP;
|
||||
float dist_px_sq = SQUARE(*dist_px);
|
||||
|
||||
float orig_camera_mat[4][4], orig_camera_imat[4][4], imat[4][4];
|
||||
bool retval = false;
|
||||
@@ -880,7 +951,7 @@ static bool snapCamera(
|
||||
invert_m4_m4(orig_camera_imat, orig_camera_mat);
|
||||
invert_m4_m4(imat, obmat);
|
||||
|
||||
switch (snap_to) {
|
||||
switch (snapdata->snap_to) {
|
||||
case SCE_SNAP_MODE_VERTEX:
|
||||
{
|
||||
MovieTrackingObject *tracking_object;
|
||||
@@ -920,7 +991,9 @@ static bool snapCamera(
|
||||
|
||||
mul_m4_v3(vertex_obmat, bundle_pos);
|
||||
retval |= test_projected_vert_dist(
|
||||
&projectdefs, bundle_pos, view_proj, mval, depth_range, r_loc);
|
||||
snapdata->depth_range, snapdata->mval, bundle_pos,
|
||||
snapdata->pmat, snapdata->win_half, is_persp, &dist_px_sq,
|
||||
r_loc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -931,7 +1004,7 @@ static bool snapCamera(
|
||||
}
|
||||
|
||||
if (retval) {
|
||||
*dist_px = sqrtf(projectdefs.dist_px_sq);
|
||||
*dist_px = sqrtf(dist_px_sq);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -943,18 +1016,10 @@ static int dm_looptri_to_poly_index(DerivedMesh *dm, const MLoopTri *lt)
|
||||
return index_mp_to_orig ? index_mp_to_orig[lt->poly] : lt->poly;
|
||||
}
|
||||
|
||||
struct NearestDM_Data {
|
||||
void *bvhdata;
|
||||
const float *depth_range;
|
||||
float *ray_depth;
|
||||
};
|
||||
|
||||
static bool snapDerivedMesh(
|
||||
SnapObjectContext *sctx,
|
||||
SnapObjectContext *sctx, SnapData *snapdata,
|
||||
Object *ob, DerivedMesh *dm, float obmat[4][4], const unsigned int ob_index,
|
||||
const short snap_to, const float mval[2], const enum eViewProj view_proj, bool do_bb,
|
||||
const float ray_origin[3], const float ray_start[3], const float ray_normal[3],
|
||||
const float depth_range[2],
|
||||
bool do_bb,
|
||||
/* read/write args */
|
||||
float *ray_depth, float *dist_px,
|
||||
/* return args */
|
||||
@@ -963,12 +1028,12 @@ static bool snapDerivedMesh(
|
||||
{
|
||||
bool retval = false;
|
||||
|
||||
if (snap_to == SCE_SNAP_MODE_FACE) {
|
||||
if (snapdata->snap_to == SCE_SNAP_MODE_FACE) {
|
||||
if (dm->getNumPolys(dm) == 0) {
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
else if (snap_to == SCE_SNAP_MODE_EDGE) {
|
||||
else if (snapdata->snap_to == SCE_SNAP_MODE_EDGE) {
|
||||
if (dm->getNumEdges(dm) == 0) {
|
||||
return retval;
|
||||
}
|
||||
@@ -980,7 +1045,9 @@ static bool snapDerivedMesh(
|
||||
}
|
||||
|
||||
{
|
||||
bool need_ray_start_correction_init = (snap_to == SCE_SNAP_MODE_FACE) && (view_proj == VIEW_PROJ_ORTHO);
|
||||
bool need_ray_start_correction_init =
|
||||
(snapdata->snap_to == SCE_SNAP_MODE_FACE) &&
|
||||
(snapdata->view_proj == VIEW_PROJ_ORTHO);
|
||||
|
||||
float imat[4][4];
|
||||
float timat[3][3]; /* transpose inverse matrix for normals */
|
||||
@@ -990,8 +1057,8 @@ static bool snapDerivedMesh(
|
||||
invert_m4_m4(imat, obmat);
|
||||
transpose_m3_m4(timat, imat);
|
||||
|
||||
copy_v3_v3(ray_start_local, ray_start);
|
||||
copy_v3_v3(ray_normal_local, ray_normal);
|
||||
copy_v3_v3(ray_start_local, snapdata->ray_start);
|
||||
copy_v3_v3(ray_normal_local, snapdata->ray_dir);
|
||||
|
||||
mul_m4_v3(imat, ray_start_local);
|
||||
mul_mat3_m4_v3(imat, ray_normal_local);
|
||||
@@ -1015,7 +1082,7 @@ static bool snapDerivedMesh(
|
||||
|
||||
/* Exact value here is arbitrary (ideally we would scale in pixel-space based on 'dist_px'),
|
||||
* scale up so we can snap against verts & edges on the boundbox, see T46816. */
|
||||
if (ELEM(snap_to, SCE_SNAP_MODE_VERTEX, SCE_SNAP_MODE_EDGE)) {
|
||||
if (ELEM(snapdata->snap_to, SCE_SNAP_MODE_VERTEX, SCE_SNAP_MODE_EDGE)) {
|
||||
BKE_boundbox_scale(&bb_temp, bb, 1.0f + 1e-1f);
|
||||
bb = &bb_temp;
|
||||
}
|
||||
@@ -1044,7 +1111,7 @@ static bool snapDerivedMesh(
|
||||
}
|
||||
|
||||
int tree_index = -1;
|
||||
switch (snap_to) {
|
||||
switch (snapdata->snap_to) {
|
||||
case SCE_SNAP_MODE_FACE:
|
||||
tree_index = 2;
|
||||
break;
|
||||
@@ -1075,7 +1142,7 @@ static bool snapDerivedMesh(
|
||||
}
|
||||
|
||||
if (treedata && treedata->tree == NULL) {
|
||||
switch (snap_to) {
|
||||
switch (snapdata->snap_to) {
|
||||
case SCE_SNAP_MODE_FACE:
|
||||
bvhtree_from_mesh_looptri(treedata, dm, 0.0f, 4, 6);
|
||||
break;
|
||||
@@ -1092,12 +1159,12 @@ static bool snapDerivedMesh(
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (snap_to == SCE_SNAP_MODE_FACE) {
|
||||
if (snapdata->snap_to == SCE_SNAP_MODE_FACE) {
|
||||
/* Only use closer ray_start in case of ortho view! In perspective one, ray_start may already
|
||||
* been *inside* boundbox, leading to snap failures (see T38409).
|
||||
* Note also ar might be null (see T38435), in this case we assume ray_start is ok!
|
||||
*/
|
||||
if (view_proj == VIEW_PROJ_ORTHO) { /* do_ray_start_correction */
|
||||
if (snapdata->view_proj == VIEW_PROJ_ORTHO) { /* do_ray_start_correction */
|
||||
if (need_ray_start_correction_init) {
|
||||
/* We *need* a reasonably valid len_diff in this case.
|
||||
* Use BHVTree to find the closest face from ray_start_local.
|
||||
@@ -1116,7 +1183,7 @@ static bool snapDerivedMesh(
|
||||
}
|
||||
float ray_org_local[3];
|
||||
|
||||
copy_v3_v3(ray_org_local, ray_origin);
|
||||
copy_v3_v3(ray_org_local, snapdata->ray_origin);
|
||||
mul_m4_v3(imat, ray_org_local);
|
||||
|
||||
/* We pass a temp ray_start, set from object's boundbox, to avoid precision issues with very far
|
||||
@@ -1124,7 +1191,8 @@ static bool snapDerivedMesh(
|
||||
*/
|
||||
len_diff -= local_scale; /* make temp start point a bit away from bbox hit point. */
|
||||
madd_v3_v3v3fl(
|
||||
ray_start_local, ray_org_local, ray_normal_local, len_diff + depth_range[0] * local_scale);
|
||||
ray_start_local, ray_org_local, ray_normal_local,
|
||||
len_diff + snapdata->depth_range[0] * local_scale);
|
||||
local_depth -= len_diff;
|
||||
}
|
||||
else {
|
||||
@@ -1186,7 +1254,7 @@ static bool snapDerivedMesh(
|
||||
const ARegion *ar = sctx->v3d_data.ar;
|
||||
|
||||
float ray_org_local[3];
|
||||
copy_v3_v3(ray_org_local, ray_origin);
|
||||
copy_v3_v3(ray_org_local, snapdata->ray_origin);
|
||||
mul_m4_v3(imat, ray_org_local);
|
||||
|
||||
BVHTreeFromMeshType treedata_type = {.userdata = treedata, .type = SNAP_MESH};
|
||||
@@ -1195,11 +1263,11 @@ static bool snapDerivedMesh(
|
||||
neasrest_precalc.userdata = &treedata_type;
|
||||
neasrest_precalc.index = -1;
|
||||
|
||||
nearest2d_precalc(&neasrest_precalc, ar, *dist_px, obmat,
|
||||
ray_org_local, ray_normal_local, mval, depth_range);
|
||||
nearest2d_precalc(&neasrest_precalc, snapdata, *dist_px, obmat,
|
||||
ray_org_local, ray_normal_local);
|
||||
|
||||
BVHTree_WalkLeafCallback cb_walk_leaf =
|
||||
(snap_to == SCE_SNAP_MODE_VERTEX) ?
|
||||
(snapdata->snap_to == SCE_SNAP_MODE_VERTEX) ?
|
||||
cb_walk_leaf_snap_vert : cb_walk_leaf_snap_edge;
|
||||
|
||||
BLI_bvhtree_walk_dfs(
|
||||
@@ -1214,7 +1282,7 @@ static bool snapDerivedMesh(
|
||||
mul_m3_v3(timat, r_no);
|
||||
normalize_v3(r_no);
|
||||
}
|
||||
*dist_px = sqrtf(neasrest_precalc.projectdefs.dist_px_sq);
|
||||
*dist_px = sqrtf(neasrest_precalc.dist_px_sq);
|
||||
|
||||
retval = true;
|
||||
}
|
||||
@@ -1231,11 +1299,8 @@ static bool snapDerivedMesh(
|
||||
}
|
||||
|
||||
static bool snapEditMesh(
|
||||
SnapObjectContext *sctx,
|
||||
SnapObjectContext *sctx, SnapData *snapdata,
|
||||
Object *ob, BMEditMesh *em, float obmat[4][4], const unsigned int ob_index,
|
||||
const short snap_to, const float mval[2], const enum eViewProj view_proj,
|
||||
const float ray_origin[3], const float ray_start[3], const float ray_normal[3],
|
||||
const float depth_range[2],
|
||||
/* read/write args */
|
||||
float *ray_depth, float *dist_px,
|
||||
/* return args */
|
||||
@@ -1244,12 +1309,12 @@ static bool snapEditMesh(
|
||||
{
|
||||
bool retval = false;
|
||||
|
||||
if (snap_to == SCE_SNAP_MODE_FACE) {
|
||||
if (snapdata->snap_to == SCE_SNAP_MODE_FACE) {
|
||||
if (em->bm->totface == 0) {
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
if (snap_to == SCE_SNAP_MODE_EDGE) {
|
||||
if (snapdata->snap_to == SCE_SNAP_MODE_EDGE) {
|
||||
if (em->bm->totedge == 0) {
|
||||
return retval;
|
||||
}
|
||||
@@ -1268,7 +1333,7 @@ static bool snapEditMesh(
|
||||
invert_m4_m4(imat, obmat);
|
||||
transpose_m3_m4(timat, imat);
|
||||
|
||||
copy_v3_v3(ray_normal_local, ray_normal);
|
||||
copy_v3_v3(ray_normal_local, snapdata->ray_dir);
|
||||
|
||||
mul_mat3_m4_v3(imat, ray_normal_local);
|
||||
|
||||
@@ -1287,7 +1352,7 @@ static bool snapEditMesh(
|
||||
}
|
||||
|
||||
int tree_index = -1;
|
||||
switch (snap_to) {
|
||||
switch (snapdata->snap_to) {
|
||||
case SCE_SNAP_MODE_FACE:
|
||||
tree_index = 2;
|
||||
break;
|
||||
@@ -1311,7 +1376,7 @@ static bool snapEditMesh(
|
||||
}
|
||||
|
||||
if (treedata && treedata->tree == NULL) {
|
||||
switch (snap_to) {
|
||||
switch (snapdata->snap_to) {
|
||||
case SCE_SNAP_MODE_FACE:
|
||||
{
|
||||
BLI_bitmap *looptri_mask = NULL;
|
||||
@@ -1369,9 +1434,9 @@ static bool snapEditMesh(
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (snap_to == SCE_SNAP_MODE_FACE) {
|
||||
if (snapdata->snap_to == SCE_SNAP_MODE_FACE) {
|
||||
float ray_start_local[3];
|
||||
copy_v3_v3(ray_start_local, ray_start);
|
||||
copy_v3_v3(ray_start_local, snapdata->ray_start);
|
||||
mul_m4_v3(imat, ray_start_local);
|
||||
|
||||
/* local scale in normal direction */
|
||||
@@ -1386,7 +1451,7 @@ static bool snapEditMesh(
|
||||
* Note also ar might be null (see T38435), in this case we assume ray_start is ok!
|
||||
*/
|
||||
float len_diff = 0.0f;
|
||||
if (view_proj == VIEW_PROJ_ORTHO) { /* do_ray_start_correction */
|
||||
if (snapdata->view_proj == VIEW_PROJ_ORTHO) { /* do_ray_start_correction */
|
||||
/* We *need* a reasonably valid len_diff in this case.
|
||||
* Use BHVTree to find the closest face from ray_start_local.
|
||||
*/
|
||||
@@ -1402,7 +1467,7 @@ static bool snapEditMesh(
|
||||
len_diff = dot_v3v3(dvec, ray_normal_local);
|
||||
float ray_org_local[3];
|
||||
|
||||
copy_v3_v3(ray_org_local, ray_origin);
|
||||
copy_v3_v3(ray_org_local, snapdata->ray_origin);
|
||||
mul_m4_v3(imat, ray_org_local);
|
||||
|
||||
/* We pass a temp ray_start, set from object's boundbox,
|
||||
@@ -1411,7 +1476,8 @@ static bool snapEditMesh(
|
||||
*/
|
||||
len_diff -= local_scale; /* make temp start point a bit away from bbox hit point. */
|
||||
madd_v3_v3v3fl(
|
||||
ray_start_local, ray_org_local, ray_normal_local, len_diff + depth_range[0] * local_scale);
|
||||
ray_start_local, ray_org_local, ray_normal_local,
|
||||
len_diff + snapdata->depth_range[0] * local_scale);
|
||||
local_depth -= len_diff;
|
||||
}
|
||||
}
|
||||
@@ -1470,7 +1536,7 @@ static bool snapEditMesh(
|
||||
const ARegion *ar = sctx->v3d_data.ar;
|
||||
|
||||
float ray_org_local[3];
|
||||
copy_v3_v3(ray_org_local, ray_origin);
|
||||
copy_v3_v3(ray_org_local, snapdata->ray_origin);
|
||||
mul_m4_v3(imat, ray_org_local);
|
||||
|
||||
BVHTreeFromMeshType treedata_type = {.userdata = treedata, .type = SNAP_EDIT_MESH};
|
||||
@@ -1479,11 +1545,11 @@ static bool snapEditMesh(
|
||||
neasrest_precalc.userdata = &treedata_type;
|
||||
neasrest_precalc.index = -1;
|
||||
|
||||
nearest2d_precalc(&neasrest_precalc, ar, *dist_px, obmat,
|
||||
ray_org_local, ray_normal_local, mval, depth_range);
|
||||
nearest2d_precalc(&neasrest_precalc, snapdata, *dist_px, obmat,
|
||||
ray_org_local, ray_normal_local);
|
||||
|
||||
BVHTree_WalkLeafCallback cb_walk_leaf =
|
||||
(snap_to == SCE_SNAP_MODE_VERTEX) ?
|
||||
(snapdata->snap_to == SCE_SNAP_MODE_VERTEX) ?
|
||||
cb_walk_leaf_snap_vert : cb_walk_leaf_snap_edge;
|
||||
|
||||
BLI_bvhtree_walk_dfs(
|
||||
@@ -1498,7 +1564,7 @@ static bool snapEditMesh(
|
||||
mul_m3_v3(timat, r_no);
|
||||
normalize_v3(r_no);
|
||||
}
|
||||
*dist_px = sqrtf(neasrest_precalc.projectdefs.dist_px_sq);
|
||||
*dist_px = sqrtf(neasrest_precalc.dist_px_sq);
|
||||
|
||||
retval = true;
|
||||
}
|
||||
@@ -1520,11 +1586,9 @@ static bool snapEditMesh(
|
||||
* \note Duplicate args here are documented at #snapObjectsRay
|
||||
*/
|
||||
static bool snapObject(
|
||||
SnapObjectContext *sctx,
|
||||
SnapObjectContext *sctx, SnapData *snapdata,
|
||||
Object *ob, float obmat[4][4], const unsigned int ob_index,
|
||||
bool use_obedit, const short snap_to, const float mval[2],
|
||||
const float ray_origin[3], const float ray_start[3], const float ray_normal[3],
|
||||
const float depth_range[2],
|
||||
bool use_obedit,
|
||||
/* read/write args */
|
||||
float *ray_depth, float *dist_px,
|
||||
/* return args */
|
||||
@@ -1532,12 +1596,6 @@ static bool snapObject(
|
||||
Object **r_ob, float r_obmat[4][4],
|
||||
ListBase *r_hit_list)
|
||||
{
|
||||
const enum eViewProj view_proj =
|
||||
((sctx->use_v3d == false) || (mval == NULL)) ? VIEW_PROJ_NONE :
|
||||
(((RegionView3D *)sctx->v3d_data.ar->regiondata)->is_persp ? VIEW_PROJ_PERSP : VIEW_PROJ_ORTHO);
|
||||
|
||||
const ARegion *ar = sctx->v3d_data.ar;
|
||||
|
||||
bool retval = false;
|
||||
|
||||
if (ob->type == OB_MESH) {
|
||||
@@ -1546,9 +1604,7 @@ static bool snapObject(
|
||||
if (use_obedit) {
|
||||
em = BKE_editmesh_from_object(ob);
|
||||
retval = snapEditMesh(
|
||||
sctx, ob, em, obmat, ob_index,
|
||||
snap_to, mval, view_proj,
|
||||
ray_origin, ray_start, ray_normal, depth_range,
|
||||
sctx, snapdata, ob, em, obmat, ob_index,
|
||||
ray_depth, dist_px,
|
||||
r_loc, r_no, r_index,
|
||||
r_hit_list);
|
||||
@@ -1565,9 +1621,8 @@ static bool snapObject(
|
||||
dm = mesh_get_derived_final(sctx->scene, ob, CD_MASK_BAREMESH);
|
||||
}
|
||||
retval = snapDerivedMesh(
|
||||
sctx, ob, dm, obmat, ob_index,
|
||||
snap_to, mval, view_proj, true,
|
||||
ray_origin, ray_start, ray_normal, depth_range,
|
||||
sctx, snapdata, ob, dm, obmat, ob_index,
|
||||
true,
|
||||
ray_depth, dist_px,
|
||||
r_loc, r_no,
|
||||
r_index, r_hit_list);
|
||||
@@ -1575,31 +1630,30 @@ static bool snapObject(
|
||||
dm->release(dm);
|
||||
}
|
||||
}
|
||||
else if (snap_to != SCE_SNAP_MODE_FACE) {
|
||||
else if (snapdata->snap_to != SCE_SNAP_MODE_FACE) {
|
||||
if (ob->type == OB_ARMATURE) {
|
||||
retval = snapArmature(
|
||||
ar, ob, ob->data, obmat, snap_to, ray_origin, ray_normal,
|
||||
mval, view_proj, depth_range, dist_px,
|
||||
snapdata,
|
||||
ob, ob->data, obmat, dist_px,
|
||||
r_loc, r_no);
|
||||
}
|
||||
else if (ob->type == OB_CURVE) {
|
||||
retval = snapCurve(
|
||||
ar, ob, ob->data, obmat, snap_to, mval, view_proj,
|
||||
depth_range,
|
||||
snapdata,
|
||||
ob, ob->data, obmat,
|
||||
dist_px,
|
||||
r_loc, r_no);
|
||||
}
|
||||
else if (ob->type == OB_EMPTY) {
|
||||
retval = snapEmpty(
|
||||
ar, ob, obmat, snap_to, mval, view_proj,
|
||||
depth_range,
|
||||
snapdata,
|
||||
ob, obmat,
|
||||
dist_px,
|
||||
r_loc, r_no);
|
||||
}
|
||||
else if (ob->type == OB_CAMERA) {
|
||||
retval = snapCamera(
|
||||
sctx, ob, obmat, snap_to, mval, view_proj,
|
||||
depth_range,
|
||||
sctx, snapdata, ob, obmat,
|
||||
dist_px,
|
||||
r_loc, r_no);
|
||||
}
|
||||
@@ -1622,18 +1676,9 @@ static bool snapObject(
|
||||
* Walks through all objects in the scene to find the closest snap element ray.
|
||||
*
|
||||
* \param sctx: Snap context to store data.
|
||||
* \param snap_to: Element to snap, Vertice, Edge or Face.
|
||||
* Currently only works one at a time, but can eventually operate as flag.
|
||||
*
|
||||
* \param snapdata: struct generated in `get_snapdata`.
|
||||
* \param snap_select: from enum SnapSelect.
|
||||
*
|
||||
* \param use_object_edit_cage: Uses the coordinates of BMesh (if any) to do the snapping.
|
||||
* \param mval: Mouse coords.
|
||||
* When NULL, ray-casting is handled without any projection matrix correction.
|
||||
* \param ray_origin: ray_start before being moved toward the ray_normal at the distance from vew3d clip_min.
|
||||
* \param ray_start: ray_origin moved for the start clipping plane (clip_min).
|
||||
* \param ray_normal: Unit length direction of the ray.
|
||||
* \param depth_range: distances of clipe plane min and clip plane max;
|
||||
*
|
||||
* Read/Write Args
|
||||
* ---------------
|
||||
@@ -1654,11 +1699,9 @@ static bool snapObject(
|
||||
*
|
||||
*/
|
||||
static bool snapObjectsRay(
|
||||
SnapObjectContext *sctx,
|
||||
const unsigned short snap_to, const SnapSelect snap_select,
|
||||
const bool use_object_edit_cage, const float mval[2],
|
||||
const float ray_origin[3], const float ray_start[3], const float ray_normal[3],
|
||||
const float depth_range[2],
|
||||
SnapObjectContext *sctx, SnapData *snapdata,
|
||||
const SnapSelect snap_select,
|
||||
const bool use_object_edit_cage,
|
||||
/* read/write args */
|
||||
float *ray_depth, float *dist_px,
|
||||
/* return args */
|
||||
@@ -1681,9 +1724,7 @@ static bool snapObjectsRay(
|
||||
Object *ob = base_act->object;
|
||||
|
||||
retval |= snapObject(
|
||||
sctx, ob, ob->obmat, ob_index++,
|
||||
false, snap_to, mval,
|
||||
ray_origin, ray_start, ray_normal, depth_range,
|
||||
sctx, snapdata, ob, ob->obmat, ob_index++, false,
|
||||
ray_depth, dist_px,
|
||||
r_loc, r_no, r_index, r_ob, r_obmat, r_hit_list);
|
||||
}
|
||||
@@ -1717,9 +1758,8 @@ static bool snapObjectsRay(
|
||||
Object *dupli_snap = (use_obedit_dupli) ? obedit : dupli_ob->ob;
|
||||
|
||||
retval |= snapObject(
|
||||
sctx, dupli_snap, dupli_ob->mat, ob_index++,
|
||||
use_obedit_dupli, snap_to, mval,
|
||||
ray_origin, ray_start, ray_normal, depth_range,
|
||||
sctx, snapdata, dupli_snap, dupli_ob->mat,
|
||||
ob_index++, use_obedit_dupli,
|
||||
ray_depth, dist_px,
|
||||
r_loc, r_no, r_index, r_ob, r_obmat, r_hit_list);
|
||||
}
|
||||
@@ -1731,9 +1771,7 @@ static bool snapObjectsRay(
|
||||
Object *ob_snap = use_obedit ? obedit : ob;
|
||||
|
||||
retval |= snapObject(
|
||||
sctx, ob_snap, ob->obmat, ob_index++,
|
||||
use_obedit, snap_to, mval,
|
||||
ray_origin, ray_start, ray_normal, depth_range,
|
||||
sctx, snapdata, ob_snap, ob->obmat, ob_index++, use_obedit,
|
||||
ray_depth, dist_px,
|
||||
r_loc, r_no, r_index, r_ob, r_obmat, r_hit_list);
|
||||
}
|
||||
@@ -1842,10 +1880,13 @@ bool ED_transform_snap_object_project_ray_ex(
|
||||
Object **r_ob, float r_obmat[4][4])
|
||||
{
|
||||
const float depth_range[2] = {0.0f, FLT_MAX};
|
||||
|
||||
SnapData snapdata;
|
||||
set_SnapData(&snapdata, sctx->v3d_data.ar, snap_to, VIEW_PROJ_NONE, NULL, r_loc, r_loc, r_no, depth_range);
|
||||
|
||||
return snapObjectsRay(
|
||||
sctx,
|
||||
snap_to, params->snap_select, params->use_object_edit_cage, NULL,
|
||||
ray_start, ray_start, ray_normal, depth_range,
|
||||
sctx, &snapdata,
|
||||
params->snap_select, params->use_object_edit_cage,
|
||||
ray_depth, NULL,
|
||||
r_loc, r_no, r_index, r_ob, r_obmat, NULL);
|
||||
}
|
||||
@@ -1874,10 +1915,13 @@ bool ED_transform_snap_object_project_ray_all(
|
||||
float ray_depth_prev = ray_depth;
|
||||
#endif
|
||||
|
||||
SnapData snapdata;
|
||||
set_SnapData(&snapdata, sctx->v3d_data.ar, snap_to, VIEW_PROJ_NONE, NULL,
|
||||
ray_start, ray_start, ray_normal, depth_range);
|
||||
|
||||
bool retval = snapObjectsRay(
|
||||
sctx,
|
||||
snap_to, params->snap_select, params->use_object_edit_cage, NULL,
|
||||
ray_start, ray_start, ray_normal, depth_range,
|
||||
sctx, &snapdata,
|
||||
params->snap_select, params->use_object_edit_cage,
|
||||
&ray_depth, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
r_hit_list);
|
||||
@@ -2037,10 +2081,14 @@ bool ED_transform_snap_object_project_view3d_ex(
|
||||
ray_depth = &ray_depth_fallback;
|
||||
}
|
||||
|
||||
SnapData snapdata;
|
||||
const enum eViewProj view_proj = ((RegionView3D *)ar->regiondata)->is_persp ? VIEW_PROJ_PERSP : VIEW_PROJ_ORTHO;
|
||||
set_SnapData(&snapdata, ar, snap_to, view_proj, mval,
|
||||
ray_start, ray_start, ray_normal, depth_range);
|
||||
|
||||
return snapObjectsRay(
|
||||
sctx,
|
||||
snap_to, params->snap_select, params->use_object_edit_cage,
|
||||
mval, ray_origin, ray_start, ray_normal, depth_range,
|
||||
sctx, &snapdata,
|
||||
params->snap_select, params->use_object_edit_cage,
|
||||
ray_depth, dist_px,
|
||||
r_loc, r_no, r_index, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user