Merge branch 'blender-v4.2-release'
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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. */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user