/** * \param r_distance Distance to the hit point */ static bool walk_floor_distance_get(bContext *C, RegionView3D *rv3d, WalkInfo *walk, const float dvec[3], float *r_distance) { float dummy_dist_px = 0; float ray_normal[3] = {0, 0, -1}; /* down */ float ray_start[3]; float r_location[3]; float r_normal[3]; float dvec_tmp[3]; bool ret; *r_distance = TRANSFORM_DIST_MAX_RAY; copy_v3_v3(ray_start, rv3d->viewinv[3]); mul_v3_v3fl(dvec_tmp, dvec, walk->grid); add_v3_v3(ray_start, dvec_tmp); ret = snapObjectsRayEx(CTX_data_scene(C), NULL, NULL, NULL, NULL, SCE_SNAP_MODE_FACE, NULL, NULL, ray_start, ray_normal, r_distance, NULL, &dummy_dist_px, r_location, r_normal, SNAP_ALL); /* artifically scale the distance to the scene size */ *r_distance /= walk->grid; return ret; }
/** * \param ray_distance Distance to the hit point * \param r_location Location of the hit point * \param r_normal Normal of the hit surface, transformed to always face the camera */ static bool walk_ray_cast(bContext *C, RegionView3D *rv3d, WalkInfo *walk, float r_location[3], float r_normal[3], float *ray_distance) { float dummy_dist_px = 0; float ray_normal[3] = {0, 0, 1}; /* forward */ float ray_start[3]; float mat[3][3]; /* 3x3 copy of the view matrix so we can move along the view axis */ bool ret; *ray_distance = TRANSFORM_DIST_MAX_RAY; copy_v3_v3(ray_start, rv3d->viewinv[3]); copy_m3_m4(mat, rv3d->viewinv); mul_m3_v3(mat, ray_normal); mul_v3_fl(ray_normal, -1); normalize_v3(ray_normal); ret = snapObjectsRayEx(CTX_data_scene(C), NULL, NULL, NULL, NULL, SCE_SNAP_MODE_FACE, NULL, NULL, ray_start, ray_normal, ray_distance, NULL, &dummy_dist_px, r_location, r_normal, SNAP_ALL); /* dot is positive if both rays are facing the same direction */ if (dot_v3v3(ray_normal, r_normal) > 0) { copy_v3_fl3(r_normal, -r_normal[0], -r_normal[1], -r_normal[2]); } /* artifically scale the distance to the scene size */ *ray_distance /= walk->grid; return ret; }
static void rna_Scene_ray_cast(Scene *scene, float ray_start[3], float ray_end[3], int *r_success, Object **r_ob, float r_obmat[16], float r_location[3], float r_normal[3]) { float dummy_dist_px = 0; float ray_nor[3]; float ray_dist; sub_v3_v3v3(ray_nor, ray_end, ray_start); ray_dist = normalize_v3(ray_nor); if (snapObjectsRayEx(scene, NULL, NULL, NULL, NULL, SCE_SNAP_MODE_FACE, r_ob, (float(*)[4])r_obmat, ray_start, ray_nor, &ray_dist, NULL, &dummy_dist_px, r_location, r_normal, SNAP_ALL)) { *r_success = true; } else { unit_m4((float(*)[4])r_obmat); zero_v3(r_location); zero_v3(r_normal); *r_success = false; } }
static bool ED_view3d_snap_ray(bContext *C, float r_co[3], const float ray_start[3], const float ray_normal[3]) { float dist_px = MVAL_MAX_PX_DIST; /* snap dist */ float r_no_dummy[3]; float ray_dist = TRANSFORM_DIST_MAX_RAY; bool ret; Scene *scene = CTX_data_scene(C); struct Object *obedit = CTX_data_edit_object(C); /* try snap edge, then face if it fails */ ret = snapObjectsRayEx(scene, NULL, NULL, NULL, obedit, SCE_SNAP_MODE_FACE, NULL, NULL, ray_start, ray_normal, &ray_dist, NULL, &dist_px, r_co, r_no_dummy, SNAP_ALL); return ret; }