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
	 ickshonpe
						ickshonpe