mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-12 02:02:20 +00:00
fixed sprite flipping issues + added ability to flip x/y
- fixed incorrect sprite size if used arbitrary uv rect - #838
This commit is contained in:
@@ -22,22 +22,21 @@
|
||||
//!
|
||||
//! For more info see [`Sprite`].
|
||||
|
||||
use crate::scene::node::constructor::NodeConstructor;
|
||||
use crate::scene::node::RdcControlFlow;
|
||||
use crate::{
|
||||
core::{
|
||||
algebra::{Vector2, Vector3},
|
||||
algebra::{Vector2, Vector3, Vector4},
|
||||
color::Color,
|
||||
math::{aabb::AxisAlignedBoundingBox, Rect, TriangleDefinition},
|
||||
pool::Handle,
|
||||
reflect::prelude::*,
|
||||
type_traits::prelude::*,
|
||||
uuid::{uuid, Uuid},
|
||||
value_as_u8_slice,
|
||||
variable::InheritableVariable,
|
||||
visitor::{Visit, VisitResult, Visitor},
|
||||
},
|
||||
material,
|
||||
material::{Material, MaterialResource},
|
||||
graph::{constructor::ConstructorProvider, BaseSceneGraph},
|
||||
material::{self, Material, MaterialResource},
|
||||
renderer::{self, bundle::RenderContext},
|
||||
scene::{
|
||||
base::{Base, BaseBuilder},
|
||||
@@ -49,13 +48,10 @@ use crate::{
|
||||
},
|
||||
RenderPath,
|
||||
},
|
||||
node::{Node, NodeTrait},
|
||||
node::{constructor::NodeConstructor, Node, NodeTrait, RdcControlFlow},
|
||||
},
|
||||
};
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use fyrox_core::value_as_u8_slice;
|
||||
use fyrox_graph::constructor::ConstructorProvider;
|
||||
use fyrox_graph::BaseSceneGraph;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
/// A vertex for sprites.
|
||||
@@ -66,8 +62,8 @@ pub struct SpriteVertex {
|
||||
pub position: Vector3<f32>,
|
||||
/// Texture coordinates.
|
||||
pub tex_coord: Vector2<f32>,
|
||||
/// Sprite parameters: x - size, y - rotation.
|
||||
pub params: Vector2<f32>,
|
||||
/// Sprite parameters: x - size, y - rotation, z - dx, w - dy.
|
||||
pub params: Vector4<f32>,
|
||||
/// Diffuse color.
|
||||
pub color: Color,
|
||||
}
|
||||
@@ -94,7 +90,7 @@ impl VertexTrait for SpriteVertex {
|
||||
VertexAttributeDescriptor {
|
||||
usage: VertexAttributeUsage::Custom0,
|
||||
data_type: VertexAttributeDataType::F32,
|
||||
size: 2,
|
||||
size: 4,
|
||||
divisor: 0,
|
||||
shader_location: 2,
|
||||
normalized: false,
|
||||
@@ -175,6 +171,12 @@ pub struct Sprite {
|
||||
|
||||
#[reflect(setter = "set_rotation")]
|
||||
rotation: InheritableVariable<f32>,
|
||||
|
||||
#[reflect(setter = "set_flip_x")]
|
||||
flip_x: InheritableVariable<bool>,
|
||||
|
||||
#[reflect(setter = "set_flip_y")]
|
||||
flip_y: InheritableVariable<bool>,
|
||||
}
|
||||
|
||||
impl Visit for Sprite {
|
||||
@@ -199,6 +201,8 @@ impl Visit for Sprite {
|
||||
self.rotation.visit("Rotation", &mut region)?;
|
||||
|
||||
// Backward compatibility.
|
||||
let _ = self.flip_x.visit("FlipX", &mut region);
|
||||
let _ = self.flip_y.visit("FlipY", &mut region);
|
||||
let _ = self.uv_rect.visit("UvRect", &mut region);
|
||||
|
||||
Ok(())
|
||||
@@ -293,6 +297,26 @@ impl Sprite {
|
||||
pub fn set_uv_rect(&mut self, uv_rect: Rect<f32>) -> Rect<f32> {
|
||||
self.uv_rect.set_value_and_mark_modified(uv_rect)
|
||||
}
|
||||
|
||||
/// Enables (`true`) or disables (`false`) horizontal flipping of the sprite.
|
||||
pub fn set_flip_x(&mut self, flip: bool) -> bool {
|
||||
self.flip_x.set_value_and_mark_modified(flip)
|
||||
}
|
||||
|
||||
/// Returns `true` if the sprite is flipped horizontally, `false` - otherwise.
|
||||
pub fn is_flip_x(&self) -> bool {
|
||||
*self.flip_x
|
||||
}
|
||||
|
||||
/// Enables (`true`) or disables (`false`) vertical flipping of the sprite.
|
||||
pub fn set_flip_y(&mut self, flip: bool) -> bool {
|
||||
self.flip_y.set_value_and_mark_modified(flip)
|
||||
}
|
||||
|
||||
/// Returns `true` if the sprite is flipped vertically, `false` - otherwise.
|
||||
pub fn is_flip_y(&self) -> bool {
|
||||
*self.flip_y
|
||||
}
|
||||
}
|
||||
|
||||
impl ConstructorProvider<Node, Graph> for Sprite {
|
||||
@@ -328,38 +352,54 @@ impl NodeTrait for Sprite {
|
||||
}
|
||||
|
||||
let position = self.global_position();
|
||||
let params = Vector2::new(*self.size, *self.rotation);
|
||||
|
||||
type Vertex = SpriteVertex;
|
||||
|
||||
let lx = self.uv_rect.position.x;
|
||||
let rx = self.uv_rect.position.x + self.uv_rect.size.x;
|
||||
let ty = self.uv_rect.position.y;
|
||||
let by = self.uv_rect.position.y + self.uv_rect.size.y;
|
||||
|
||||
let vertices = [
|
||||
Vertex {
|
||||
position,
|
||||
tex_coord: self.uv_rect.right_top_corner(),
|
||||
params,
|
||||
tex_coord: Vector2::new(
|
||||
if *self.flip_x { lx } else { rx },
|
||||
if *self.flip_y { by } else { ty },
|
||||
),
|
||||
params: Vector4::new(*self.size, *self.rotation, 0.5, 0.5),
|
||||
color: *self.color,
|
||||
},
|
||||
Vertex {
|
||||
position,
|
||||
tex_coord: self.uv_rect.left_top_corner(),
|
||||
params,
|
||||
tex_coord: Vector2::new(
|
||||
if *self.flip_x { rx } else { lx },
|
||||
if *self.flip_y { by } else { ty },
|
||||
),
|
||||
params: Vector4::new(*self.size, *self.rotation, -0.5, 0.5),
|
||||
color: *self.color,
|
||||
},
|
||||
Vertex {
|
||||
position,
|
||||
tex_coord: self.uv_rect.left_bottom_corner(),
|
||||
params,
|
||||
tex_coord: Vector2::new(
|
||||
if *self.flip_x { rx } else { lx },
|
||||
if *self.flip_y { ty } else { by },
|
||||
),
|
||||
params: Vector4::new(*self.size, *self.rotation, -0.5, -0.5),
|
||||
color: *self.color,
|
||||
},
|
||||
Vertex {
|
||||
position,
|
||||
tex_coord: self.uv_rect.right_bottom_corner(),
|
||||
params,
|
||||
tex_coord: Vector2::new(
|
||||
if *self.flip_x { lx } else { rx },
|
||||
if *self.flip_y { ty } else { by },
|
||||
),
|
||||
params: Vector4::new(*self.size, *self.rotation, 0.5, -0.5),
|
||||
color: *self.color,
|
||||
},
|
||||
];
|
||||
|
||||
let triangles = [TriangleDefinition([0, 1, 2]), TriangleDefinition([2, 3, 0])];
|
||||
let triangles = [TriangleDefinition([0, 1, 2]), TriangleDefinition([0, 2, 3])];
|
||||
|
||||
let sort_index = ctx.calculate_sorting_index(self.global_position());
|
||||
|
||||
@@ -397,6 +437,8 @@ pub struct SpriteBuilder {
|
||||
color: Color,
|
||||
size: f32,
|
||||
rotation: f32,
|
||||
flip_x: bool,
|
||||
flip_y: bool,
|
||||
}
|
||||
|
||||
impl SpriteBuilder {
|
||||
@@ -413,6 +455,8 @@ impl SpriteBuilder {
|
||||
color: Color::WHITE,
|
||||
size: 0.2,
|
||||
rotation: 0.0,
|
||||
flip_x: false,
|
||||
flip_y: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,6 +491,18 @@ impl SpriteBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Flips the sprite horizontally.
|
||||
pub fn with_flip_x(mut self, flip_x: bool) -> Self {
|
||||
self.flip_x = flip_x;
|
||||
self
|
||||
}
|
||||
|
||||
/// Flips the sprite vertically.
|
||||
pub fn with_flip_y(mut self, flip_y: bool) -> Self {
|
||||
self.flip_y = flip_y;
|
||||
self
|
||||
}
|
||||
|
||||
fn build_sprite(self) -> Sprite {
|
||||
Sprite {
|
||||
base: self.base_builder.build_base(),
|
||||
@@ -455,6 +511,8 @@ impl SpriteBuilder {
|
||||
color: self.color.into(),
|
||||
size: self.size.into(),
|
||||
rotation: self.rotation.into(),
|
||||
flip_x: self.flip_x.into(),
|
||||
flip_y: self.flip_y.into(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
r#"
|
||||
layout(location = 0) in vec3 vertexPosition;
|
||||
layout(location = 1) in vec2 vertexTexCoord;
|
||||
layout(location = 2) in vec2 vertexParams;
|
||||
layout(location = 2) in vec4 vertexParams;
|
||||
layout(location = 3) in vec4 vertexColor;
|
||||
|
||||
out vec2 texCoord;
|
||||
@@ -73,10 +73,12 @@
|
||||
{
|
||||
float size = vertexParams.x;
|
||||
float rotation = vertexParams.y;
|
||||
float dx = vertexParams.z;
|
||||
float dy = vertexParams.w;
|
||||
|
||||
texCoord = vertexTexCoord;
|
||||
color = vertexColor;
|
||||
vec2 vertexOffset = S_RotateVec2(vertexTexCoord * 2.0 - 1.0, rotation);
|
||||
vec2 vertexOffset = S_RotateVec2(vec2(dx, dy), rotation);
|
||||
vec4 worldPosition = fyrox_instanceData.worldMatrix * vec4(vertexPosition, 1.0);
|
||||
vec3 offset = (vertexOffset.x * fyrox_cameraData.sideVector + vertexOffset.y * fyrox_cameraData.upVector) * size;
|
||||
gl_Position = fyrox_cameraData.viewProjectionMatrix * (worldPosition + vec4(offset.x, offset.y, offset.z, 0.0));
|
||||
|
||||
Reference in New Issue
Block a user