Merge branch 'blender-v4.2-release'

This commit is contained in:
Germano Cavalcante
2024-06-08 16:11:18 -03:00
7 changed files with 103 additions and 84 deletions

View File

@@ -360,6 +360,18 @@ float closest_to_line_segment_v3(float r_close[3],
const float p[3],
const float l1[3],
const float l2[3]);
/**
* Finds the points where a ray and a segment are closest to each other.
*
* \return A value in [0, 1] that corresponds to the position of #r_close on the line segment.
*/
float closest_ray_to_segment_v3(const float ray_origin[3],
const float ray_direction[3],
const float v0[3],
const float v1[3],
float r_close[3]);
void closest_to_plane_normalized_v3(float r_close[3], const float plane[4], const float pt[3]);
/**
* Find the closest point on a plane.

View File

@@ -404,6 +404,32 @@ float closest_to_line_segment_v3(float r_close[3],
return lambda;
}
float closest_ray_to_segment_v3(const float ray_origin[3],
const float ray_direction[3],
const float v0[3],
const float v1[3],
float r_close[3])
{
float lambda;
if (!isect_ray_line_v3(ray_origin, ray_direction, v0, v1, &lambda)) {
copy_v3_v3(r_close, v0);
return 0.0f;
}
if (lambda <= 0.0f) {
copy_v3_v3(r_close, v0);
return 0.0f;
}
if (lambda >= 1.0f) {
copy_v3_v3(r_close, v1);
return 1.0f;
}
interp_v3_v3v3(r_close, v0, v1, lambda);
return lambda;
}
void closest_to_plane_v3(float r_close[3], const float plane[4], const float pt[3])
{
const float len_sq = len_squared_v3(plane);

View File

@@ -20,7 +20,6 @@
shared uint tiles_local[SHADOW_TILEDATA_PER_TILEMAP];
shared uint levels_rendered;
shared uint force_base_page;
shared uint base_page_do_update_flag;
int shadow_tile_offset_lds(ivec2 tile, int lod)
{
@@ -58,11 +57,6 @@ void main()
ShadowTileDataPacked tile_data = tiles_buf[tile_offset];
if ((tile_data & SHADOW_IS_USED) == 0) {
if (lod == SHADOW_TILEMAP_LOD) {
/* Save the flag to recover it if needed. This is fine to write non-atomically because
* there is only one tile at the base level. */
base_page_do_update_flag = tile_data & SHADOW_DO_UPDATE;
}
/* Do not consider this tile as going to be rendered if it is not used.
* Simplify checks later. This is a local modification. */
tile_data &= ~SHADOW_DO_UPDATE;
@@ -112,14 +106,6 @@ void main()
/* Visibility value to write back. */
tiles_local[tile_offset] |= SHADOW_TILE_MASKED;
}
else if ((lod == SHADOW_TILEMAP_LOD) && (force_base_page != 0u)) {
/* Recover the update flag value. */
tiles_local[tile_offset] |= base_page_do_update_flag;
/* Tag as modified so that we can amend it inside the `tiles_buf`. */
tiles_local[tile_offset] |= SHADOW_TILE_AMENDED;
/* Visibility value to write back. */
tiles_local[tile_offset] &= ~SHADOW_TILE_MASKED;
}
}
}
#endif
@@ -187,6 +173,25 @@ void main()
barrier();
#if 1 /* Can be disabled for debugging. */
if (gl_LocalInvocationIndex == 0u) {
/* WATCH: To be kept in sync with `max_view_per_tilemap()` function. */
bool is_render = max_view_per_tilemap == SHADOW_TILEMAP_LOD;
/* Tag base page to be rendered if any other tile is needed by this shadow.
* Fixes issue with shadow map ray tracing sampling invalide tiles.
* Only do this in for final render or if all the main levels were already rendered.
* This last heuristic avoids very low quality shadows during viewport animation, transform
* or jittered shadows. */
if ((force_base_page != 0u) && ((levels_rendered == 0u) || is_render)) {
int tile_offset = shadow_tile_offset_lds(ivec2(0), SHADOW_TILEMAP_LOD);
/* Tag as modified so that we can amend it inside the `tiles_buf`. */
tiles_local[tile_offset] |= SHADOW_TILE_AMENDED;
/* Visibility value to write back. */
tiles_local[tile_offset] &= ~SHADOW_TILE_MASKED;
}
}
#endif
/* Flush back visibility bits to the tile SSBO. */
for (int lod = 0; lod <= SHADOW_TILEMAP_LOD; lod++) {
if (thread_mask(tile_co, lod)) {

View File

@@ -115,8 +115,9 @@ struct KnifeVert {
* -1 represents the absence of an object. */
int ob_index;
float co[3], cageco[3];
bool is_cut; /* Along a cut created by user input (will draw too). */
float co[3]; /* Vertex position in the original mesh. Equivalent to #BMVert::co[3]. */
float cageco[3]; /* Vertex position in the Cage mesh and in World Space. */
bool is_cut; /* Along a cut created by user input (will draw too). */
bool is_invalid;
bool is_splitting; /* Created when an edge was split. */
};
@@ -3095,19 +3096,18 @@ static void knife_pos_data_clear(KnifePosData *kpd)
/** \name Snapping (#knife_snap_update_from_mval)
* \{ */
static bool knife_find_closest_face(KnifeTool_OpData *kcd, const float2 &mval, KnifePosData *r_kpd)
static bool knife_find_closest_face(KnifeTool_OpData *kcd,
const float3 ray_origin,
const float3 ray_normal,
const float2 &mval,
KnifePosData *r_kpd)
{
float3 cage;
int ob_index;
BMFace *f;
float dist = KMAXDIST;
float3 origin;
float3 ray_normal;
ED_view3d_win_to_ray_clipped(
kcd->vc.depsgraph, kcd->region, kcd->vc.v3d, mval, origin, ray_normal, false);
f = knife_bvh_raycast(kcd, origin, ray_normal, 0.0f, nullptr, cage, &ob_index);
f = knife_bvh_raycast(kcd, ray_origin, ray_normal, 0.0f, nullptr, cage, &ob_index);
if (f && kcd->only_select && BM_elem_flag_test(f, BM_ELEM_SELECT) == 0) {
f = nullptr;
@@ -3132,7 +3132,7 @@ static bool knife_find_closest_face(KnifeTool_OpData *kcd, const float2 &mval, K
/* Cheat for now; just put in the origin instead
* of a true coordinate on the face.
* This just puts a point 1.0f in front of the view. */
cage = origin + ray_normal;
cage = ray_origin + ray_normal;
ob_index = 0;
BLI_assert(ob_index == kcd->objects.first_index_of_try(vc.obact));
@@ -3230,7 +3230,6 @@ static bool knife_snap_edge_constrained(KnifeTool_OpData *kcd,
const float kfv1_sco[2],
const float kfv2_sco[2],
float *r_dist_sq,
float *r_lambda,
float2 &r_sco)
{
/* If snapping, check we're in bounds. */
@@ -3245,33 +3244,19 @@ static bool knife_snap_edge_constrained(KnifeTool_OpData *kcd,
float dis_sq = len_squared_v2v2(sco, r_sco);
if (dis_sq < *r_dist_sq) {
*r_dist_sq = dis_sq;
*r_lambda = lambda;
return true;
}
return false;
}
/* Use when lambda is in screen-space. */
static void knife_interp_v3_v3v3(const KnifeTool_OpData *kcd,
float r_co[3],
const float v1[3],
const float v2[3],
const float lambda_ss)
{
float lambda = lambda_ss;
if (!kcd->is_ortho) {
/* Adjust the lambda according to the perspective. */
float w1 = mul_project_m4_v3_zfac(kcd->vc.rv3d->persmat, v1);
float w2 = mul_project_m4_v3_zfac(kcd->vc.rv3d->persmat, v2);
lambda = (lambda_ss * w1) / (w2 + (lambda_ss * (w1 - w2)));
}
interp_v3_v3v3(r_co, v1, v2, lambda);
}
/* p is closest point on edge to the mouse cursor. */
static bool knife_find_closest_edge_of_face(
KnifeTool_OpData *kcd, int ob_index, BMFace *f, const float2 &cage_ss, KnifePosData *r_kpd)
static bool knife_find_closest_edge_of_face(KnifeTool_OpData *kcd,
int ob_index,
BMFace *f,
const float3 ray_origin,
const float3 ray_normal,
const float2 &mval,
KnifePosData *r_kpd)
{
float maxdist;
@@ -3295,7 +3280,6 @@ static bool knife_find_closest_edge_of_face(
LISTBASE_FOREACH (LinkData *, ref, list) {
KnifeEdge *kfe = static_cast<KnifeEdge *>(ref->data);
float kfv1_sco[2], kfv2_sco[2], test_cagep[3];
float lambda;
if (kfe->is_invalid) {
continue;
@@ -3313,26 +3297,21 @@ static bool knife_find_closest_edge_of_face(
(kcd->mode == MODE_DRAGGING))
{
dis_sq = cur_dist_sq;
if (!knife_snap_edge_constrained(
kcd, cage_ss, kfv1_sco, kfv2_sco, &dis_sq, &lambda, closest_ss))
{
if (!knife_snap_edge_constrained(kcd, mval, kfv1_sco, kfv2_sco, &dis_sq, closest_ss)) {
continue;
}
}
else {
closest_to_line_segment_v2(closest_ss, cage_ss, kfv1_sco, kfv2_sco);
dis_sq = len_squared_v2v2(closest_ss, cage_ss);
if (dis_sq < cur_dist_sq) {
lambda = line_point_factor_v2(cage_ss, kfv1_sco, kfv2_sco);
}
else {
closest_ray_to_segment_v3(
ray_origin, ray_normal, kfe->v1->cageco, kfe->v2->cageco, test_cagep);
knife_project_v2(kcd, test_cagep, closest_ss);
dis_sq = len_squared_v2v2(closest_ss, mval);
if (dis_sq >= cur_dist_sq) {
continue;
}
}
/* Now we have 'lambda' calculated (in screen-space). */
knife_interp_v3_v3v3(kcd, test_cagep, kfe->v1->cageco, kfe->v2->cageco, lambda);
if (RV3D_CLIPPING_ENABLED(kcd->vc.v3d, kcd->vc.rv3d)) {
/* Check we're in the view */
if (ED_view3d_clipping_test(kcd->vc.rv3d, test_cagep, false)) {
@@ -3744,11 +3723,16 @@ static void knife_snap_curr(KnifeTool_OpData *kcd, const float2 &mval)
{
knife_pos_data_clear(&kcd->curr);
if (knife_find_closest_face(kcd, mval, &kcd->curr)) {
float3 ray_origin;
float3 ray_normal;
ED_view3d_win_to_ray_clipped(
kcd->vc.depsgraph, kcd->region, kcd->vc.v3d, mval, ray_origin, ray_normal, false);
if (knife_find_closest_face(kcd, ray_origin, ray_normal, mval, &kcd->curr)) {
if (!kcd->ignore_edge_snapping || !kcd->ignore_vert_snapping) {
KnifePosData kpos_tmp = kcd->curr;
if (knife_find_closest_edge_of_face(
kcd, kpos_tmp.ob_index, kpos_tmp.bmface, kpos_tmp.mval, &kpos_tmp))
kcd, kpos_tmp.ob_index, kpos_tmp.bmface, ray_origin, ray_normal, mval, &kpos_tmp))
{
if (!kcd->ignore_edge_snapping) {
kcd->curr = kpos_tmp;

View File

@@ -183,6 +183,7 @@ static void edge_slide_data_init_mval(MouseInput *mi, EdgeSlideData *sld, float
static bool is_vert_slide_visible(TransInfo *t,
SnapObjectContext *sctx,
TransDataEdgeSlideVert *sv,
const float4x4 &obmat,
const float4 &plane_near)
{
const float3 &v_co_orig = sv->v_co_orig();
@@ -193,7 +194,8 @@ static bool is_vert_slide_visible(TransInfo *t,
};
float3 hit_loc;
for (const float3 &p : points) {
for (float3 &p : points) {
p = math::transform_point(obmat, p);
float3 view_vec;
float lambda, ray_depth = FLT_MAX;
@@ -249,13 +251,17 @@ static void calcEdgeSlide_mval_range(TransInfo *t,
/* Use for visibility checks. */
SnapObjectContext *snap_context = nullptr;
bool use_occlude_geometry = false;
const float4x4 *obmat = nullptr;
float4 plane_near;
if (t->spacetype == SPACE_VIEW3D) {
View3D *v3d = static_cast<View3D *>(t->area ? t->area->spacedata.first : nullptr);
use_occlude_geometry = (v3d && TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->dt > OB_WIRE &&
!XRAY_ENABLED(v3d));
planes_from_projmat(t->persmat, nullptr, nullptr, nullptr, nullptr, plane_near, nullptr);
snap_context = ED_transform_snap_object_context_create(t->scene, 0);
Object *obedit = TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit;
use_occlude_geometry = (v3d && obedit->dt > OB_WIRE && !XRAY_ENABLED(v3d));
if (use_occlude_geometry) {
obmat = &obedit->object_to_world();
planes_from_projmat(t->persmat, nullptr, nullptr, nullptr, nullptr, plane_near, nullptr);
snap_context = ED_transform_snap_object_context_create(t->scene, 0);
}
}
/* Find mouse vectors, the global one, and one per loop in case we have
@@ -276,7 +282,7 @@ static void calcEdgeSlide_mval_range(TransInfo *t,
for (int i : sld->sv.index_range()) {
TransDataEdgeSlideVert *sv = &sld->sv[i];
bool is_visible = !use_occlude_geometry ||
is_vert_slide_visible(t, snap_context, sv, plane_near);
is_vert_slide_visible(t, snap_context, sv, *obmat, plane_near);
/* This test is only relevant if object is not wire-drawn! See #32068. */
if (!is_visible && !use_calc_direction) {

View File

@@ -94,21 +94,7 @@ static bool test_projected_edge_dist(const DistProjectedAABBPrecalc *precalc,
BVHTreeNearest *nearest)
{
float near_co[3], lambda;
if (!isect_ray_line_v3(precalc->ray_origin, precalc->ray_direction, va, vb, &lambda)) {
copy_v3_v3(near_co, va);
}
else {
if (lambda <= 0.0f) {
copy_v3_v3(near_co, va);
}
else if (lambda >= 1.0f) {
copy_v3_v3(near_co, vb);
}
else {
interp_v3_v3v3(near_co, va, vb, lambda);
}
}
lambda = closest_ray_to_segment_v3(precalc->ray_origin, precalc->ray_direction, va, vb, near_co);
return test_projected_vert_dist(precalc, clip_plane, clip_plane_len, is_persp, near_co, nearest);
}

View File

@@ -224,7 +224,7 @@ typedef enum eIDPropertySubType {
} eIDPropertySubType;
/** #IDProperty.flag. */
enum {
typedef enum eIDPropertyFlag {
/**
* This #IDProperty may be library-overridden.
* Should only be used/be relevant for custom properties.
@@ -241,7 +241,7 @@ enum {
* #RNA_property_is_set, currently this is a runtime flag.
*/
IDP_FLAG_GHOST = 1 << 7,
};
} eIDPropertyFlag;
/* add any future new id property types here. */