Fix the UV calculations for clipped and flipped ImageNodes (#8195)
# Objective Instead of flipping the entire image, `prepare_ui_nodes` only flips the unclipped area. <img width="652" alt="overflow_flipped_bug" src="https://user-images.githubusercontent.com/27962798/227587867-1467c6ae-8693-45c3-87cb-793cc5b433e4.png"> ## Solution Whenever flip_x or flip_y is set swap the image rect coordinates and invert the clipping coords along the flipped axes before the UVs are calculated. <img width="656" alt="overflow_fixed" src="https://user-images.githubusercontent.com/27962798/227588839-e0dde3b9-dc26-4652-a129-2faab2d07281.PNG"> -- ## Changelog * Modified `prepare_uinodes` so that the UVs for clipped and flipped image nodes are calculated correctly.
This commit is contained in:
parent
ffc62c1a81
commit
43d7184b35
@ -414,7 +414,8 @@ pub fn prepare_uinodes(
|
|||||||
current_batch_handle = extracted_uinode.image.clone_weak();
|
current_batch_handle = extracted_uinode.image.clone_weak();
|
||||||
}
|
}
|
||||||
|
|
||||||
let uinode_rect = extracted_uinode.rect;
|
let mut uinode_rect = extracted_uinode.rect;
|
||||||
|
|
||||||
let rect_size = uinode_rect.size().extend(1.0);
|
let rect_size = uinode_rect.size().extend(1.0);
|
||||||
|
|
||||||
// Specify the corners of the node
|
// Specify the corners of the node
|
||||||
@ -423,7 +424,7 @@ pub fn prepare_uinodes(
|
|||||||
|
|
||||||
// Calculate the effect of clipping
|
// Calculate the effect of clipping
|
||||||
// Note: this won't work with rotation/scaling, but that's much more complex (may need more that 2 quads)
|
// Note: this won't work with rotation/scaling, but that's much more complex (may need more that 2 quads)
|
||||||
let positions_diff = if let Some(clip) = extracted_uinode.clip {
|
let mut positions_diff = if let Some(clip) = extracted_uinode.clip {
|
||||||
[
|
[
|
||||||
Vec2::new(
|
Vec2::new(
|
||||||
f32::max(clip.min.x - positions[0].x, 0.),
|
f32::max(clip.min.x - positions[0].x, 0.),
|
||||||
@ -473,7 +474,21 @@ pub fn prepare_uinodes(
|
|||||||
[Vec2::ZERO, Vec2::X, Vec2::ONE, Vec2::Y]
|
[Vec2::ZERO, Vec2::X, Vec2::ONE, Vec2::Y]
|
||||||
} else {
|
} else {
|
||||||
let atlas_extent = extracted_uinode.atlas_size.unwrap_or(uinode_rect.max);
|
let atlas_extent = extracted_uinode.atlas_size.unwrap_or(uinode_rect.max);
|
||||||
let mut uvs = [
|
if extracted_uinode.flip_x {
|
||||||
|
std::mem::swap(&mut uinode_rect.max.x, &mut uinode_rect.min.x);
|
||||||
|
positions_diff[0].x *= -1.;
|
||||||
|
positions_diff[1].x *= -1.;
|
||||||
|
positions_diff[2].x *= -1.;
|
||||||
|
positions_diff[3].x *= -1.;
|
||||||
|
}
|
||||||
|
if extracted_uinode.flip_y {
|
||||||
|
std::mem::swap(&mut uinode_rect.max.y, &mut uinode_rect.min.y);
|
||||||
|
positions_diff[0].y *= -1.;
|
||||||
|
positions_diff[1].y *= -1.;
|
||||||
|
positions_diff[2].y *= -1.;
|
||||||
|
positions_diff[3].y *= -1.;
|
||||||
|
}
|
||||||
|
[
|
||||||
Vec2::new(
|
Vec2::new(
|
||||||
uinode_rect.min.x + positions_diff[0].x,
|
uinode_rect.min.x + positions_diff[0].x,
|
||||||
uinode_rect.min.y + positions_diff[0].y,
|
uinode_rect.min.y + positions_diff[0].y,
|
||||||
@ -491,15 +506,7 @@ pub fn prepare_uinodes(
|
|||||||
uinode_rect.max.y + positions_diff[3].y,
|
uinode_rect.max.y + positions_diff[3].y,
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
.map(|pos| pos / atlas_extent);
|
.map(|pos| pos / atlas_extent)
|
||||||
|
|
||||||
if extracted_uinode.flip_x {
|
|
||||||
uvs = [uvs[1], uvs[0], uvs[3], uvs[2]];
|
|
||||||
}
|
|
||||||
if extracted_uinode.flip_y {
|
|
||||||
uvs = [uvs[3], uvs[2], uvs[1], uvs[0]];
|
|
||||||
}
|
|
||||||
uvs
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let color = extracted_uinode.color.as_linear_rgba_f32();
|
let color = extracted_uinode.color.as_linear_rgba_f32();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user