diff options
-rw-r--r-- | source/blender/blenkernel/BKE_object.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 12 | ||||
-rw-r--r-- | source/blender/editors/include/ED_view3d.h | 2 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_project.c | 122 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_snap.c | 281 |
5 files changed, 243 insertions, 177 deletions
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 33c9583db8b..38055dd1ec5 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -124,7 +124,8 @@ void BKE_object_where_is_calc_mat4(struct Scene *scene, struct Object *ob, float /* possibly belong in own moduke? */ struct BoundBox *BKE_boundbox_alloc_unit(void); void BKE_boundbox_init_from_minmax(struct BoundBox *bb, const float min[3], const float max[3]); -bool BKE_boundbox_ray_hit_check(struct BoundBox *bb, const float ray_start[3], const float ray_normal[3]); +bool BKE_boundbox_ray_hit_check(struct BoundBox *bb, const float ray_start[3], const float ray_normal[3], + float *r_lambda); struct BoundBox *BKE_object_boundbox_get(struct Object *ob); void BKE_object_dimensions_get(struct Object *ob, float vec[3]); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index dc20629b0d0..019885df935 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -3131,7 +3131,8 @@ int BKE_object_obdata_texspace_get(Object *ob, short **r_texflag, float **r_loc, * Test a bounding box for ray intersection * assumes the ray is already local to the boundbox space */ -bool BKE_boundbox_ray_hit_check(struct BoundBox *bb, const float ray_start[3], const float ray_normal[3]) +bool BKE_boundbox_ray_hit_check(struct BoundBox *bb, const float ray_start[3], const float ray_normal[3], + float *r_lambda) { const int triangle_indexes[12][3] = { {0, 1, 2}, {0, 2, 3}, @@ -3144,13 +3145,18 @@ bool BKE_boundbox_ray_hit_check(struct BoundBox *bb, const float ray_start[3], c bool result = false; int i; - for (i = 0; i < 12 && result == 0; i++) { + for (i = 0; i < 12 && (!result || r_lambda); i++) { float lambda; int v1, v2, v3; v1 = triangle_indexes[i][0]; v2 = triangle_indexes[i][1]; v3 = triangle_indexes[i][2]; - result = isect_ray_tri_v3(ray_start, ray_normal, bb->vec[v1], bb->vec[v2], bb->vec[v3], &lambda, NULL); + if (isect_ray_tri_v3(ray_start, ray_normal, bb->vec[v1], bb->vec[v2], bb->vec[v3], &lambda, NULL) && + (!r_lambda || *r_lambda > lambda)) + { + result = true; + *r_lambda = lambda; + } } return result; diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index f155247f851..a76c904acdd 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -200,6 +200,8 @@ eV3DProjStatus ED_view3d_project_float_object(const struct ARegion *ar, const fl float ED_view3d_calc_zfac(const struct RegionView3D *rv3d, const float co[3], bool *r_flip); bool ED_view3d_win_to_ray(const struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3], const bool do_clip); +bool ED_view3d_win_to_ray_ex(const struct ARegion *ar, struct View3D *v3d, const float mval[2], + float r_ray_co[3], float r_ray_normal[3], float r_ray_start[3], bool do_clip); void ED_view3d_global_to_vector(const struct RegionView3D *rv3d, const float coord[3], float vec[3]); void ED_view3d_win_to_3d(const struct ARegion *ar, const float depth_pt[3], const float mval[2], float out[3]); void ED_view3d_win_to_3d_int(const struct ARegion *ar, const float depth_pt[3], const int mval[2], float out[3]); diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c index 0954563be14..0c3539889c0 100644 --- a/source/blender/editors/space_view3d/view3d_project.c +++ b/source/blender/editors/space_view3d/view3d_project.c @@ -302,29 +302,102 @@ float ED_view3d_calc_zfac(const RegionView3D *rv3d, const float co[3], bool *r_f return zfac; } +static void view3d_win_to_ray_segment(const ARegion *ar, View3D *v3d, const float mval[2], + float r_ray_co[3], float r_ray_dir[3], float r_ray_start[3], float r_ray_end[3]) +{ + RegionView3D *rv3d = ar->regiondata; + float _ray_co[3], _ray_dir[3], start_offset, end_offset; + + if (!r_ray_co) r_ray_co = _ray_co; + if (!r_ray_dir) r_ray_dir = _ray_dir; + + ED_view3d_win_to_vector(ar, mval, r_ray_dir); + negate_v3(r_ray_dir); + + if (rv3d->is_persp) { + copy_v3_v3(r_ray_co, rv3d->viewinv[3]); + + start_offset = -v3d->near; + end_offset = -v3d->far; + } + else { + float vec[4]; + vec[0] = 2.0f * mval[0] / ar->winx - 1; + vec[1] = 2.0f * mval[1] / ar->winy - 1; + vec[2] = 0.0f; + vec[3] = 1.0f; + + mul_m4_v4(rv3d->persinv, vec); + copy_v3_v3(r_ray_co, vec); + + start_offset = -1000.0f; + end_offset = 1000.0f; + } + + if (r_ray_start) { + madd_v3_v3v3fl(r_ray_start, r_ray_co, r_ray_dir, start_offset); + } + if (r_ray_end) { + madd_v3_v3v3fl(r_ray_end, r_ray_co, r_ray_dir, end_offset); + } +} + +BLI_INLINE bool view3d_clip_segment(RegionView3D *rv3d, float ray_start[3], float ray_end[3]) +{ + if ((rv3d->rflag & RV3D_CLIPPING) && !clip_segment_v3_plane_n(ray_start, ray_end, rv3d->clip, 6)) { + return false; + } + return true; +} + /** * Calculate a 3d viewpoint and direction vector from 2d window coordinates. * This ray_start is located at the viewpoint, ray_normal is the direction towards mval. * ray_start is clipped by the view near limit so points in front of it are always in view. * In orthographic view the resulting ray_normal will match the view vector. + * This version also returns the ray_co point of the ray on window plane, useful to fix precision + * issues esp. with ortho view, where default ray_start is set rather far away. * \param ar The region (used for the window width and height). * \param v3d The 3d viewport (used for near clipping value). * \param mval The area relative 2d location (such as event->mval, converted into float[2]). - * \param r_ray_start The world-space starting point of the segment. + * \param r_ray_co The world-space point where the ray intersects the window plane. * \param r_ray_normal The normalized world-space direction of towards mval. - * \param do_clip Optionally clip the ray by the view clipping planes. - * \return success, false if the segment is totally clipped. + * \param r_ray_start The world-space starting point of the ray. + * \param do_clip Optionally clip the start of the ray by the view clipping planes. + * \return success, false if the ray is totally clipped. + */ +bool ED_view3d_win_to_ray_ex(const ARegion *ar, View3D *v3d, const float mval[2], + float r_ray_co[3], float r_ray_normal[3], float r_ray_start[3], bool do_clip) +{ + float ray_end[3]; + + view3d_win_to_ray_segment(ar, v3d, mval, r_ray_co, r_ray_normal, r_ray_start, ray_end); + + /* bounds clipping */ + if (do_clip) { + return view3d_clip_segment((RegionView3D *)ar->regiondata, r_ray_start, ray_end); + } + + return true; +} + +/** + * Calculate a 3d viewpoint and direction vector from 2d window coordinates. + * This ray_start is located at the viewpoint, ray_normal is the direction towards mval. + * ray_start is clipped by the view near limit so points in front of it are always in view. + * In orthographic view the resulting ray_normal will match the view vector. + * \param ar The region (used for the window width and height). + * \param v3d The 3d viewport (used for near clipping value). + * \param mval The area relative 2d location (such as event->mval, converted into float[2]). + * \param r_ray_co The world-space point where the ray intersects the window plane. + * \param r_ray_normal The normalized world-space direction of towards mval. + * \param do_clip Optionally clip the start of the ray by the view clipping planes. + * \return success, false if the ray is totally clipped. */ bool ED_view3d_win_to_ray(const ARegion *ar, View3D *v3d, const float mval[2], float r_ray_start[3], float r_ray_normal[3], const bool do_clip) { - float ray_end[3]; - bool is_clip; - - is_clip = ED_view3d_win_to_segment(ar, v3d, mval, r_ray_start, ray_end, do_clip); - sub_v3_v3v3(r_ray_normal, ray_end, r_ray_start); - normalize_v3(r_ray_normal); - return is_clip; + return ED_view3d_win_to_ray_ex(ar, v3d, mval, NULL, r_ray_normal, r_ray_start, do_clip); } /** @@ -507,34 +580,11 @@ void ED_view3d_win_to_vector(const ARegion *ar, const float mval[2], float out[3 bool ED_view3d_win_to_segment(const ARegion *ar, View3D *v3d, const float mval[2], float r_ray_start[3], float r_ray_end[3], const bool do_clip) { - RegionView3D *rv3d = ar->regiondata; - - if (rv3d->is_persp) { - float vec[3]; - ED_view3d_win_to_vector(ar, mval, vec); - - copy_v3_v3(r_ray_start, rv3d->viewinv[3]); - madd_v3_v3v3fl(r_ray_start, rv3d->viewinv[3], vec, v3d->near); - madd_v3_v3v3fl(r_ray_end, rv3d->viewinv[3], vec, v3d->far); - } - else { - float vec[4]; - vec[0] = 2.0f * mval[0] / ar->winx - 1; - vec[1] = 2.0f * mval[1] / ar->winy - 1; - vec[2] = 0.0f; - vec[3] = 1.0f; - - mul_m4_v4(rv3d->persinv, vec); - - madd_v3_v3v3fl(r_ray_start, vec, rv3d->viewinv[2], 1000.0f); - madd_v3_v3v3fl(r_ray_end, vec, rv3d->viewinv[2], -1000.0f); - } + view3d_win_to_ray_segment(ar, v3d, mval, NULL, NULL, r_ray_start, r_ray_end); /* bounds clipping */ - if (do_clip && (rv3d->rflag & RV3D_CLIPPING)) { - if (clip_segment_v3_plane_n(r_ray_start, r_ray_end, rv3d->clip, 6) == false) { - return false; - } + if (do_clip) { + return view3d_clip_segment((RegionView3D *)ar->regiondata, r_ray_start, r_ray_end); } return true; diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 7df5c5ff77e..694b2931e19 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -1504,21 +1504,19 @@ static bool snapCurve(short snap_mode, ARegion *ar, Object *ob, Curve *cu, float } static bool snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, BMEditMesh *em, float obmat[4][4], - const float ray_start[3], const float ray_normal[3], const float mval[2], - float r_loc[3], float r_no[3], float *r_dist_px, float *r_depth) + const float ray_start[3], const float ray_normal[3], const float ray_origin[3], + const float mval[2], float r_loc[3], float r_no[3], float *r_dist_px, float *r_depth) { bool retval = false; int totvert = dm->getNumVerts(dm); - int totface = dm->getNumTessFaces(dm); if (totvert > 0) { + BoundBox *bb; float imat[4][4]; float timat[3][3]; /* transpose inverse matrix for normals */ - float ray_start_local[3], ray_normal_local[3]; - int test = 1; + float ray_start_local[3], ray_normal_local[3], len_diff = TRANSFORM_DIST_MAX_RAY; invert_m4_m4(imat, obmat); - copy_m3_m4(timat, imat); transpose_m3(timat); @@ -1527,149 +1525,157 @@ static bool snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMes mul_m4_v3(imat, ray_start_local); mul_mat3_m4_v3(imat, ray_normal_local); - - - /* If number of vert is more than an arbitrary limit, - * test against boundbox first - * */ - if (totface > 16) { - struct BoundBox *bb = BKE_object_boundbox_get(ob); - test = BKE_boundbox_ray_hit_check(bb, ray_start_local, ray_normal_local); + + bb = BKE_object_boundbox_get(ob); + if (!BKE_boundbox_ray_hit_check(bb, ray_start_local, ray_normal_local, &len_diff)) { + return retval; } - - if (test == 1) { - - switch (snap_mode) { - case SCE_SNAP_MODE_FACE: - { - BVHTreeRayHit hit; - BVHTreeFromMesh treeData; - /* local scale in normal direction */ - float local_scale = len_v3(ray_normal_local); + switch (snap_mode) { + case SCE_SNAP_MODE_FACE: + { + BVHTreeRayHit hit; + BVHTreeFromMesh treeData; + float ray_org_local[3], local_scale; - treeData.em_evil = em; - bvhtree_from_mesh_faces(&treeData, dm, 0.0f, 4, 6); + copy_v3_v3(ray_org_local, ray_origin); + mul_m4_v3(imat, ray_org_local); - hit.index = -1; - hit.dist = *r_depth * (*r_depth == TRANSFORM_DIST_MAX_RAY ? 1.0f : local_scale); + /* local scale in normal direction */ + local_scale = len_v3(ray_normal_local); + normalize_v3(ray_normal_local); - if (treeData.tree && BLI_bvhtree_ray_cast(treeData.tree, ray_start_local, ray_normal_local, 0.0f, &hit, treeData.raycast_callback, &treeData) != -1) { - if (hit.dist / local_scale <= *r_depth) { - *r_depth = hit.dist / local_scale; - copy_v3_v3(r_loc, hit.co); - copy_v3_v3(r_no, hit.no); + /* We pass a temp ray_start, set from object's boundbox, to avoid precision issues with very far + * away ray_start values (as returned in case of ortho view3d), see T38358. + */ + 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 - len_v3v3(ray_start_local, ray_org_local)); - /* back to worldspace */ - mul_m4_v3(obmat, r_loc); - copy_v3_v3(r_no, hit.no); + treeData.em_evil = em; + bvhtree_from_mesh_faces(&treeData, dm, 0.0f, 4, 6); - mul_m3_v3(timat, r_no); - normalize_v3(r_no); + hit.index = -1; + hit.dist = *r_depth * (*r_depth == TRANSFORM_DIST_MAX_RAY ? 1.0f : local_scale); - retval |= 1; - } + if (treeData.tree && + BLI_bvhtree_ray_cast(treeData.tree, ray_start_local, ray_normal_local, 0.0f, + &hit, treeData.raycast_callback, &treeData) != -1) + { + hit.dist += len_diff; + hit.dist /= local_scale; + if (hit.dist <= *r_depth) { + *r_depth = hit.dist; + copy_v3_v3(r_loc, hit.co); + copy_v3_v3(r_no, hit.no); + + /* back to worldspace */ + mul_m4_v3(obmat, r_loc); + mul_m3_v3(timat, r_no); + normalize_v3(r_no); + + retval = true; } - free_bvhtree_from_mesh(&treeData); - break; } - case SCE_SNAP_MODE_VERTEX: - { - MVert *verts = dm->getVertArray(dm); - int *index_array = NULL; - int index = 0; - int i; - + free_bvhtree_from_mesh(&treeData); + break; + } + case SCE_SNAP_MODE_VERTEX: + { + MVert *verts = dm->getVertArray(dm); + int *index_array = NULL; + int index = 0; + int i; + + if (em != NULL) { + index_array = dm->getVertDataArray(dm, CD_ORIGINDEX); + BM_mesh_elem_table_ensure(em->bm, BM_VERT); + } + + for (i = 0; i < totvert; i++) { + BMVert *eve = NULL; + MVert *v = verts + i; + bool test = true; + if (em != NULL) { - index_array = dm->getVertDataArray(dm, CD_ORIGINDEX); - BM_mesh_elem_table_ensure(em->bm, BM_VERT); - } - - for (i = 0; i < totvert; i++) { - BMVert *eve = NULL; - MVert *v = verts + i; + if (index_array) { + index = index_array[i]; + } + else { + index = i; + } - test = 1; /* reset for every vert */ - - if (em != NULL) { - if (index_array) { - index = index_array[i]; - } - else { - index = i; - } + if (index == ORIGINDEX_NONE) { + test = false; + } + else { + eve = BM_vert_at_index(em->bm, index); - if (index == ORIGINDEX_NONE) { - test = 0; + if ((BM_elem_flag_test(eve, BM_ELEM_HIDDEN) || + BM_elem_flag_test(eve, BM_ELEM_SELECT))) + { + test = false; } - else { - eve = BM_vert_at_index(em->bm, index); - - if ((BM_elem_flag_test(eve, BM_ELEM_HIDDEN) || - BM_elem_flag_test(eve, BM_ELEM_SELECT))) - { - test = 0; - } - } - } - - - if (test) { - retval |= snapVertex(ar, v->co, v->no, obmat, timat, ray_start, ray_start_local, ray_normal_local, mval, r_loc, r_no, r_dist_px, r_depth); } } - break; + if (test) { + retval |= snapVertex(ar, v->co, v->no, obmat, timat, ray_start, ray_start_local, + ray_normal_local, mval, r_loc, r_no, r_dist_px, r_depth); + } } - case SCE_SNAP_MODE_EDGE: - { - MVert *verts = dm->getVertArray(dm); - MEdge *edges = dm->getEdgeArray(dm); - int totedge = dm->getNumEdges(dm); - int *index_array = NULL; - int index = 0; - int i; - + + break; + } + case SCE_SNAP_MODE_EDGE: + { + MVert *verts = dm->getVertArray(dm); + MEdge *edges = dm->getEdgeArray(dm); + int totedge = dm->getNumEdges(dm); + int *index_array = NULL; + int index = 0; + int i; + + if (em != NULL) { + index_array = dm->getEdgeDataArray(dm, CD_ORIGINDEX); + BM_mesh_elem_table_ensure(em->bm, BM_EDGE); + } + + for (i = 0; i < totedge; i++) { + MEdge *e = edges + i; + bool test = true; + if (em != NULL) { - index_array = dm->getEdgeDataArray(dm, CD_ORIGINDEX); - BM_mesh_elem_table_ensure(em->bm, BM_EDGE); - } - - for (i = 0; i < totedge; i++) { - MEdge *e = edges + i; - - test = 1; /* reset for every vert */ - - if (em != NULL) { - if (index_array) { - index = index_array[i]; - } - else { - index = i; - } - - if (index == ORIGINDEX_NONE) { - test = 0; - } - else { - BMEdge *eed = BM_edge_at_index(em->bm, index); - - if ((BM_elem_flag_test(eed, BM_ELEM_HIDDEN) || - BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) || - BM_elem_flag_test(eed->v2, BM_ELEM_SELECT))) - { - test = 0; - } - } + if (index_array) { + index = index_array[i]; + } + else { + index = i; + } + + if (index == ORIGINDEX_NONE) { + test = false; } + else { + BMEdge *eed = BM_edge_at_index(em->bm, index); - if (test) { - retval |= snapEdge(ar, verts[e->v1].co, verts[e->v1].no, verts[e->v2].co, verts[e->v2].no, obmat, timat, ray_start, ray_start_local, ray_normal_local, mval, r_loc, r_no, r_dist_px, r_depth); + if ((BM_elem_flag_test(eed, BM_ELEM_HIDDEN) || + BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) || + BM_elem_flag_test(eed->v2, BM_ELEM_SELECT))) + { + test = false; + } } } - break; + if (test) { + retval |= snapEdge(ar, verts[e->v1].co, verts[e->v1].no, verts[e->v2].co, verts[e->v2].no, + obmat, timat, ray_start, ray_start_local, ray_normal_local, mval, + r_loc, r_no, r_dist_px, r_depth); + } } + + break; } } } @@ -1802,8 +1808,8 @@ static bool snapCamera(short snap_mode, ARegion *ar, Scene *scene, Object *objec static bool snapObject(Scene *scene, short snap_mode, ARegion *ar, Object *ob, float obmat[4][4], bool use_obedit, Object **r_ob, float r_obmat[4][4], - const float ray_start[3], const float ray_normal[3], const float mval[2], - float r_loc[3], float r_no[3], float *r_dist_px, float *r_depth) + const float ray_start[3], const float ray_normal[3], const float ray_origin[3], + const float mval[2], float r_loc[3], float r_no[3], float *r_dist_px, float *r_depth) { bool retval = false; @@ -1820,7 +1826,7 @@ static bool snapObject(Scene *scene, short snap_mode, ARegion *ar, Object *ob, f dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); } - retval = snapDerivedMesh(snap_mode, ar, ob, dm, em, obmat, ray_start, ray_normal, mval, r_loc, r_no, r_dist_px, r_depth); + retval = snapDerivedMesh(snap_mode, ar, ob, dm, em, obmat, ray_start, ray_normal, ray_origin, mval, r_loc, r_no, r_dist_px, r_depth); dm->release(dm); } @@ -1849,7 +1855,8 @@ static bool snapObject(Scene *scene, short snap_mode, ARegion *ar, Object *ob, f static bool snapObjectsRay(Scene *scene, short snap_mode, Base *base_act, View3D *v3d, ARegion *ar, Object *obedit, Object **r_ob, float r_obmat[4][4], - const float ray_start[3], const float ray_normal[3], float *r_ray_dist, + const float ray_start[3], const float ray_normal[3], const float ray_origin[3], + float *r_ray_dist, const float mval[2], float *r_dist_px, float r_loc[3], float r_no[3], SnapMode mode) { Base *base; @@ -1860,7 +1867,7 @@ static bool snapObjectsRay(Scene *scene, short snap_mode, Base *base_act, View3D retval |= snapObject(scene, snap_mode, ar, ob, ob->obmat, true, r_ob, r_obmat, - ray_start, ray_normal, mval, r_loc, r_no, r_dist_px, r_ray_dist); + ray_start, ray_normal, ray_origin, mval, r_loc, r_no, r_dist_px, r_ray_dist); } /* Need an exception for particle edit because the base is flagged with BA_HAS_RECALC_DATA @@ -1873,7 +1880,7 @@ static bool snapObjectsRay(Scene *scene, short snap_mode, Base *base_act, View3D Object *ob = base->object; retval |= snapObject(scene, snap_mode, ar, ob, ob->obmat, false, r_ob, r_obmat, - ray_start, ray_normal, mval, r_loc, r_no, r_dist_px, r_ray_dist); + ray_start, ray_normal, ray_origin, mval, r_loc, r_no, r_dist_px, r_ray_dist); } for (base = FIRSTBASE; base != NULL; base = base->next) { @@ -1892,7 +1899,7 @@ static bool snapObjectsRay(Scene *scene, short snap_mode, Base *base_act, View3D for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) { retval |= snapObject(scene, snap_mode, ar, dupli_ob->ob, dupli_ob->mat, false, r_ob, r_obmat, - ray_start, ray_normal, mval, r_loc, r_no, r_dist_px, r_ray_dist); + ray_start, ray_normal, ray_origin, mval, r_loc, r_no, r_dist_px, r_ray_dist); } free_object_duplilist(lb); @@ -1900,7 +1907,7 @@ static bool snapObjectsRay(Scene *scene, short snap_mode, Base *base_act, View3D retval |= snapObject(scene, snap_mode, ar, ob, ob->obmat, false, r_ob, r_obmat, - ray_start, ray_normal, mval, r_loc, r_no, r_dist_px, r_ray_dist); + ray_start, ray_normal, ray_origin, mval, r_loc, r_no, r_dist_px, r_ray_dist); } } @@ -1910,15 +1917,15 @@ static bool snapObjects(Scene *scene, short snap_mode, Base *base_act, View3D *v const float mval[2], float *r_dist_px, float r_loc[3], float r_no[3], float *r_ray_dist, SnapMode mode) { - float ray_start[3], ray_normal[3]; + float ray_start[3], ray_normal[3], ray_orgigin[3]; - if (ED_view3d_win_to_ray(ar, v3d, mval, ray_start, ray_normal, true) == false) { + if (!ED_view3d_win_to_ray_ex(ar, v3d, mval, ray_orgigin, ray_normal, ray_start, true)) { return false; } return snapObjectsRay(scene, snap_mode, base_act, v3d, ar, obedit, NULL, NULL, - ray_start, ray_normal, r_ray_dist, + ray_start, ray_normal, ray_orgigin, r_ray_dist, mval, r_dist_px, r_loc, r_no, mode); } @@ -1957,7 +1964,7 @@ bool snapObjectsRayEx(Scene *scene, Base *base_act, View3D *v3d, ARegion *ar, Ob { return snapObjectsRay(scene, snap_mode, base_act, v3d, ar, obedit, r_ob, r_obmat, - ray_start, ray_normal, r_ray_dist, + ray_start, ray_normal, ray_start, r_ray_dist, mval, r_dist_px, r_loc, r_no, mode); } @@ -2044,7 +2051,7 @@ static bool peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[4][4], * */ if (totface > 16) { struct BoundBox *bb = BKE_object_boundbox_get(ob); - test = BKE_boundbox_ray_hit_check(bb, ray_start_local, ray_normal_local); + test = BKE_boundbox_ray_hit_check(bb, ray_start_local, ray_normal_local, NULL); } if (test == 1) { |