Fix T38358: Face snapping fails on Orthographic view

Issue is caused by start point of ray used to detect faces under the mouse is set rather far away in ortho 3dviews.
The loss of precision on the ray location induced by this can lead to face snapping failures.

Solution is to do the raycasting with a temp start point, much closer to the object we check, and add back
to the found distance the diff to the real start point once detection is done (as we need all hit distances
from all tested objects to be relative to a common point!).

Note this commit only addresses the "face snapping on mesh" case, other kind of snapping do not seem to suffer
from this issue.

Reviewers: brecht, campbellbarton

Differential Revision: https://developer.blender.org/D268
This commit is contained in:
Bastien Montagne 2014-01-29 20:10:03 +01:00
parent 95e153a319
commit 77089a3bf2
Notes: blender-bot 2023-02-14 11:18:00 +01:00
Referenced by commit 810c6d1880, Fix T38358: typo in own rB77089a3bf203.
Referenced by issue #38358, Face snapping fails on Orthographic view
5 changed files with 248 additions and 182 deletions

View File

@ -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]);

View File

@ -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;

View File

@ -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]);

View File

@ -302,6 +302,85 @@ 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_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 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.
@ -310,21 +389,15 @@ float ED_view3d_calc_zfac(const RegionView3D *rv3d, const float co[3], bool *r_f
* \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 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;

View File

@ -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:
switch (snap_mode) {
case SCE_SNAP_MODE_FACE:
{
BVHTreeRayHit hit;
BVHTreeFromMesh treeData;
float ray_org_local[3], local_scale;
copy_v3_v3(ray_org_local, ray_origin);
mul_m4_v3(imat, ray_org_local);
/* local scale in normal direction */
local_scale = len_v3(ray_normal_local);
normalize_v3(ray_normal_local);
/* 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));
treeData.em_evil = em;
bvhtree_from_mesh_faces(&treeData, dm, 0.0f, 4, 6);
hit.index = -1;
hit.dist = *r_depth * (*r_depth == TRANSFORM_DIST_MAX_RAY ? 1.0f : local_scale);
if (treeData.tree &&
BLI_bvhtree_ray_cast(treeData.tree, ray_start_local, ray_normal_local, 0.0f,
&hit, treeData.raycast_callback, &treeData) != -1)
{
BVHTreeRayHit hit;
BVHTreeFromMesh treeData;
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);
/* local scale in normal direction */
float local_scale = len_v3(ray_normal_local);
/* back to worldspace */
mul_m4_v3(obmat, r_loc);
mul_m3_v3(timat, r_no);
normalize_v3(r_no);
treeData.em_evil = em;
bvhtree_from_mesh_faces(&treeData, dm, 0.0f, 4, 6);
hit.index = -1;
hit.dist = *r_depth * (*r_depth == TRANSFORM_DIST_MAX_RAY ? 1.0f : local_scale);
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);
/* back to worldspace */
mul_m4_v3(obmat, r_loc);
copy_v3_v3(r_no, hit.no);
mul_m3_v3(timat, r_no);
normalize_v3(r_no);
retval |= 1;
}
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;
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 {
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 (index_array) {
index = index_array[i];
}
else {
index = i;
}
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);
if (index == ORIGINDEX_NONE) {
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 = false;
}
}
}
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 (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 (index == ORIGINDEX_NONE) {
test = false;
}
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 = 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) {