use right handed coordinate system in 3d
This commit is contained in:
parent
bd227859eb
commit
b5d3f7e794
@ -6,7 +6,7 @@ pub trait FaceToward {
|
|||||||
|
|
||||||
impl FaceToward for Mat4 {
|
impl FaceToward for Mat4 {
|
||||||
fn face_toward(eye: Vec3, center: Vec3, up: Vec3) -> Self {
|
fn face_toward(eye: Vec3, center: Vec3, up: Vec3) -> Self {
|
||||||
let forward = (center - eye).normalize();
|
let forward = (eye - center).normalize();
|
||||||
let right = up.cross(forward).normalize();
|
let right = up.cross(forward).normalize();
|
||||||
let up = forward.cross(right);
|
let up = forward.cross(right);
|
||||||
Mat4::from_cols(
|
Mat4::from_cols(
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
mod face_toward;
|
mod face_toward;
|
||||||
|
mod perspective;
|
||||||
|
|
||||||
pub use face_toward::*;
|
pub use face_toward::*;
|
||||||
pub use glam::*;
|
pub use glam::*;
|
||||||
|
pub use perspective::*;
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use crate::{FaceToward, Mat3, Mat4, Quat, Vec2, Vec3, Vec4};
|
pub use crate::{FaceToward, Mat3, Mat4, Quat, Vec2, Vec3, Vec4};
|
||||||
|
21
crates/bevy_math/src/perspective.rs
Normal file
21
crates/bevy_math/src/perspective.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
use crate::Mat4;
|
||||||
|
use glam::Vec4;
|
||||||
|
|
||||||
|
pub trait PerspectiveRh {
|
||||||
|
fn perspective_rh(fov_y_radians: f32, aspect_ratio: f32, z_near: f32, z_far: f32) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PerspectiveRh for Mat4 {
|
||||||
|
fn perspective_rh(fov_y_radians: f32, aspect_ratio: f32, z_near: f32, z_far: f32) -> Self {
|
||||||
|
let (sin_fov, cos_fov) = (0.5 * fov_y_radians).sin_cos();
|
||||||
|
let h = cos_fov / sin_fov;
|
||||||
|
let w = h /aspect_ratio;
|
||||||
|
let r = z_far / (z_near - z_far);
|
||||||
|
Mat4::from_cols(
|
||||||
|
Vec4::new(w, 0.0, 0.0, 0.0),
|
||||||
|
Vec4::new(0.0, h, 0.0, 0.0),
|
||||||
|
Vec4::new(0.0, 0.0, r, -1.0),
|
||||||
|
Vec4::new(0.0, 0.0, r * z_near, 0.0),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -14,7 +14,7 @@ pub const FORWARD_PIPELINE_HANDLE: Handle<PipelineDescriptor> =
|
|||||||
pub fn build_forward_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
|
pub fn build_forward_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
|
||||||
PipelineDescriptor {
|
PipelineDescriptor {
|
||||||
rasterization_state: Some(RasterizationStateDescriptor {
|
rasterization_state: Some(RasterizationStateDescriptor {
|
||||||
front_face: FrontFace::Cw,
|
front_face: FrontFace::Ccw,
|
||||||
cull_mode: CullMode::Back,
|
cull_mode: CullMode::Back,
|
||||||
depth_bias: 0,
|
depth_bias: 0,
|
||||||
depth_bias_slope_scale: 0.0,
|
depth_bias_slope_scale: 0.0,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use bevy_math::Mat4;
|
use bevy_math::{PerspectiveRh, Mat4};
|
||||||
use bevy_property::{Properties, Property};
|
use bevy_property::{Properties, Property};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ pub struct PerspectiveProjection {
|
|||||||
|
|
||||||
impl CameraProjection for PerspectiveProjection {
|
impl CameraProjection for PerspectiveProjection {
|
||||||
fn get_projection_matrix(&self) -> Mat4 {
|
fn get_projection_matrix(&self) -> Mat4 {
|
||||||
Mat4::perspective_lh(self.fov, self.aspect_ratio, self.near, self.far)
|
Mat4::perspective_rh(self.fov, self.aspect_ratio, self.near, self.far)
|
||||||
}
|
}
|
||||||
fn update(&mut self, width: usize, height: usize) {
|
fn update(&mut self, width: usize, height: usize) {
|
||||||
self.aspect_ratio = width as f32 / height as f32;
|
self.aspect_ratio = width as f32 / height as f32;
|
||||||
|
@ -273,14 +273,9 @@ pub mod shape {
|
|||||||
let vertices = if quad.flip {
|
let vertices = if quad.flip {
|
||||||
[
|
[
|
||||||
(
|
(
|
||||||
[south_west.x(), south_west.y(), 0.0],
|
[south_east.x(), south_east.y(), 0.0],
|
||||||
[0.0, 0.0, 1.0],
|
[0.0, 0.0, 1.0],
|
||||||
[0.0, 1.0],
|
[1.0, 1.0],
|
||||||
),
|
|
||||||
(
|
|
||||||
[north_west.x(), north_west.y(), 0.0],
|
|
||||||
[0.0, 0.0, 1.0],
|
|
||||||
[0.0, 0.0],
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
[north_east.x(), north_east.y(), 0.0],
|
[north_east.x(), north_east.y(), 0.0],
|
||||||
@ -288,22 +283,22 @@ pub mod shape {
|
|||||||
[1.0, 0.0],
|
[1.0, 0.0],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
[south_east.x(), south_east.y(), 0.0],
|
[north_west.x(), north_west.y(), 0.0],
|
||||||
[0.0, 0.0, 1.0],
|
[0.0, 0.0, 1.0],
|
||||||
[1.0, 1.0],
|
[0.0, 0.0],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
[south_west.x(), south_west.y(), 0.0],
|
||||||
|
[0.0, 0.0, 1.0],
|
||||||
|
[0.0, 1.0],
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
} else {
|
} else {
|
||||||
[
|
[
|
||||||
(
|
(
|
||||||
[south_east.x(), south_east.y(), 0.0],
|
[south_west.x(), south_west.y(), 0.0],
|
||||||
[0.0, 0.0, 1.0],
|
[0.0, 0.0, 1.0],
|
||||||
[1.0, 1.0],
|
[0.0, 1.0],
|
||||||
),
|
|
||||||
(
|
|
||||||
[north_east.x(), north_east.y(), 0.0],
|
|
||||||
[0.0, 0.0, 1.0],
|
|
||||||
[1.0, 0.0],
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
[north_west.x(), north_west.y(), 0.0],
|
[north_west.x(), north_west.y(), 0.0],
|
||||||
@ -311,9 +306,14 @@ pub mod shape {
|
|||||||
[0.0, 0.0],
|
[0.0, 0.0],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
[south_west.x(), south_west.y(), 0.0],
|
[north_east.x(), north_east.y(), 0.0],
|
||||||
[0.0, 0.0, 1.0],
|
[0.0, 0.0, 1.0],
|
||||||
[0.0, 1.0],
|
[1.0, 0.0],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
[south_east.x(), south_east.y(), 0.0],
|
||||||
|
[0.0, 0.0, 1.0],
|
||||||
|
[1.0, 1.0],
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
@ -72,7 +72,7 @@ impl PipelineDescriptor {
|
|||||||
sample_mask: !0,
|
sample_mask: !0,
|
||||||
alpha_to_coverage_enabled: false,
|
alpha_to_coverage_enabled: false,
|
||||||
rasterization_state: Some(RasterizationStateDescriptor {
|
rasterization_state: Some(RasterizationStateDescriptor {
|
||||||
front_face: FrontFace::Cw,
|
front_face: FrontFace::Ccw,
|
||||||
cull_mode: CullMode::Back,
|
cull_mode: CullMode::Back,
|
||||||
depth_bias: 0,
|
depth_bias: 0,
|
||||||
depth_bias_slope_scale: 0.0,
|
depth_bias_slope_scale: 0.0,
|
||||||
|
@ -74,7 +74,7 @@ pub enum FrontFace {
|
|||||||
|
|
||||||
impl Default for FrontFace {
|
impl Default for FrontFace {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
FrontFace::Cw
|
FrontFace::Ccw
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ impl AppPlugin for SpritePlugin {
|
|||||||
meshes.set(
|
meshes.set(
|
||||||
QUAD_HANDLE,
|
QUAD_HANDLE,
|
||||||
// Use a flipped quad because the camera is facing "forward" but quads should face backward
|
// Use a flipped quad because the camera is facing "forward" but quads should face backward
|
||||||
Mesh::from(shape::Quad::flipped(Vec2::new(1.0, 1.0))),
|
Mesh::from(shape::Quad::new(Vec2::new(1.0, 1.0))),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut color_materials = resources.get_mut::<Assets<ColorMaterial>>().unwrap();
|
let mut color_materials = resources.get_mut::<Assets<ColorMaterial>>().unwrap();
|
||||||
|
@ -21,8 +21,8 @@ pub const SPRITE_SHEET_PIPELINE_HANDLE: Handle<PipelineDescriptor> =
|
|||||||
pub fn build_sprite_sheet_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
|
pub fn build_sprite_sheet_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
|
||||||
PipelineDescriptor {
|
PipelineDescriptor {
|
||||||
rasterization_state: Some(RasterizationStateDescriptor {
|
rasterization_state: Some(RasterizationStateDescriptor {
|
||||||
front_face: FrontFace::Cw,
|
front_face: FrontFace::Ccw,
|
||||||
cull_mode: CullMode::None,
|
cull_mode: CullMode::Back,
|
||||||
depth_bias: 0,
|
depth_bias: 0,
|
||||||
depth_bias_slope_scale: 0.0,
|
depth_bias_slope_scale: 0.0,
|
||||||
depth_bias_clamp: 0.0,
|
depth_bias_clamp: 0.0,
|
||||||
@ -66,8 +66,8 @@ pub fn build_sprite_sheet_pipeline(shaders: &mut Assets<Shader>) -> PipelineDesc
|
|||||||
pub fn build_sprite_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
|
pub fn build_sprite_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
|
||||||
PipelineDescriptor {
|
PipelineDescriptor {
|
||||||
rasterization_state: Some(RasterizationStateDescriptor {
|
rasterization_state: Some(RasterizationStateDescriptor {
|
||||||
front_face: FrontFace::Cw,
|
front_face: FrontFace::Ccw,
|
||||||
cull_mode: CullMode::None,
|
cull_mode: CullMode::Back,
|
||||||
depth_bias: 0,
|
depth_bias: 0,
|
||||||
depth_bias_slope_scale: 0.0,
|
depth_bias_slope_scale: 0.0,
|
||||||
depth_bias_clamp: 0.0,
|
depth_bias_clamp: 0.0,
|
||||||
|
@ -15,8 +15,8 @@ pub const UI_PIPELINE_HANDLE: Handle<PipelineDescriptor> =
|
|||||||
pub fn build_ui_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
|
pub fn build_ui_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
|
||||||
PipelineDescriptor {
|
PipelineDescriptor {
|
||||||
rasterization_state: Some(RasterizationStateDescriptor {
|
rasterization_state: Some(RasterizationStateDescriptor {
|
||||||
front_face: FrontFace::Cw,
|
front_face: FrontFace::Ccw,
|
||||||
cull_mode: CullMode::None,
|
cull_mode: CullMode::Back,
|
||||||
depth_bias: 0,
|
depth_bias: 0,
|
||||||
depth_bias_slope_scale: 0.0,
|
depth_bias_slope_scale: 0.0,
|
||||||
depth_bias_clamp: 0.0,
|
depth_bias_clamp: 0.0,
|
||||||
|
@ -58,8 +58,8 @@ fn setup(
|
|||||||
.spawn(PbrComponents {
|
.spawn(PbrComponents {
|
||||||
mesh: quad_handle,
|
mesh: quad_handle,
|
||||||
material: material_handle,
|
material: material_handle,
|
||||||
translation: Translation::new(0.0, 0.0, -1.5),
|
translation: Translation::new(0.0, 0.0, 1.5),
|
||||||
rotation: Rotation(Quat::from_rotation_x(std::f32::consts::PI / 5.0)),
|
rotation: Rotation(Quat::from_rotation_x(-std::f32::consts::PI / 5.0)),
|
||||||
draw: Draw {
|
draw: Draw {
|
||||||
is_transparent: true,
|
is_transparent: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@ -71,7 +71,7 @@ fn setup(
|
|||||||
mesh: quad_handle,
|
mesh: quad_handle,
|
||||||
material: red_material_handle,
|
material: red_material_handle,
|
||||||
translation: Translation::new(0.0, 0.0, 0.0),
|
translation: Translation::new(0.0, 0.0, 0.0),
|
||||||
rotation: Rotation(Quat::from_rotation_x(std::f32::consts::PI / 5.0)),
|
rotation: Rotation(Quat::from_rotation_x(-std::f32::consts::PI / 5.0)),
|
||||||
draw: Draw {
|
draw: Draw {
|
||||||
is_transparent: true,
|
is_transparent: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@ -82,8 +82,8 @@ fn setup(
|
|||||||
.spawn(PbrComponents {
|
.spawn(PbrComponents {
|
||||||
mesh: quad_handle,
|
mesh: quad_handle,
|
||||||
material: blue_material_handle,
|
material: blue_material_handle,
|
||||||
translation: Translation::new(0.0, 0.0, 1.5),
|
translation: Translation::new(0.0, 0.0, -1.5),
|
||||||
rotation: Rotation(Quat::from_rotation_x(std::f32::consts::PI / 5.0)),
|
rotation: Rotation(Quat::from_rotation_x(-std::f32::consts::PI / 5.0)),
|
||||||
draw: Draw {
|
draw: Draw {
|
||||||
is_transparent: true,
|
is_transparent: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@ -93,7 +93,7 @@ fn setup(
|
|||||||
// camera
|
// camera
|
||||||
.spawn(Camera3dComponents {
|
.spawn(Camera3dComponents {
|
||||||
transform: Transform::new_sync_disabled(Mat4::face_toward(
|
transform: Transform::new_sync_disabled(Mat4::face_toward(
|
||||||
Vec3::new(3.0, 5.0, -8.0),
|
Vec3::new(3.0, 5.0, 8.0),
|
||||||
Vec3::new(0.0, 0.0, 0.0),
|
Vec3::new(0.0, 0.0, 0.0),
|
||||||
Vec3::new(0.0, 1.0, 0.0),
|
Vec3::new(0.0, 1.0, 0.0),
|
||||||
)),
|
)),
|
||||||
|
@ -42,23 +42,23 @@ fn button_system(
|
|||||||
&mut Handle<ColorMaterial>,
|
&mut Handle<ColorMaterial>,
|
||||||
&Children,
|
&Children,
|
||||||
)>,
|
)>,
|
||||||
label_query: Query<&mut Label>,
|
text_query: Query<&mut Text>,
|
||||||
) {
|
) {
|
||||||
for (_button, hover, click, mut material, children) in &mut hover_query.iter() {
|
for (_button, hover, click, mut material, children) in &mut hover_query.iter() {
|
||||||
let mut label = label_query.get_mut::<Label>(children[0]).unwrap();
|
let mut text = text_query.get_mut::<Text>(children[0]).unwrap();
|
||||||
match *hover {
|
match *hover {
|
||||||
Hover::Hovered => {
|
Hover::Hovered => {
|
||||||
if let Some(Click::Released) = click {
|
if let Some(Click::Released) = click {
|
||||||
label.text = "Hover".to_string();
|
text.value = "Hover".to_string();
|
||||||
*material = button_materials.hovered;
|
*material = button_materials.hovered;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Hover::NotHovered => {
|
Hover::NotHovered => {
|
||||||
if let Some(Click::Pressed) = click {
|
if let Some(Click::Pressed) = click {
|
||||||
label.text = "Press".to_string();
|
text.value = "Press".to_string();
|
||||||
*material = button_materials.pressed;
|
*material = button_materials.pressed;
|
||||||
} else {
|
} else {
|
||||||
label.text = "Button".to_string();
|
text.value = "Button".to_string();
|
||||||
*material = button_materials.normal;
|
*material = button_materials.normal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -66,18 +66,18 @@ fn button_system(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (_button, click, hover, mut material, children) in &mut click_query.iter() {
|
for (_button, click, hover, mut material, children) in &mut click_query.iter() {
|
||||||
let mut label = label_query.get_mut::<Label>(children[0]).unwrap();
|
let mut text = text_query.get_mut::<Text>(children[0]).unwrap();
|
||||||
match *click {
|
match *click {
|
||||||
Click::Pressed => {
|
Click::Pressed => {
|
||||||
label.text = "Press".to_string();
|
text.value = "Press".to_string();
|
||||||
*material = button_materials.pressed;
|
*material = button_materials.pressed;
|
||||||
}
|
}
|
||||||
Click::Released => {
|
Click::Released => {
|
||||||
if let Some(Hover::Hovered) = hover {
|
if let Some(Hover::Hovered) = hover {
|
||||||
label.text = "Hover".to_string();
|
text.value = "Hover".to_string();
|
||||||
*material = button_materials.hovered;
|
*material = button_materials.hovered;
|
||||||
} else {
|
} else {
|
||||||
label.text = "Button".to_string();
|
text.value = "Button".to_string();
|
||||||
*material = button_materials.normal;
|
*material = button_materials.normal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,10 +99,10 @@ fn setup(
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
parent.spawn(LabelComponents {
|
parent.spawn(TextComponents {
|
||||||
node: Node::new(Anchors::FULL, Margins::new(0.0, 0.0, 12.0, 0.0)),
|
node: Node::new(Anchors::FULL, Margins::new(0.0, 0.0, 12.0, 0.0)),
|
||||||
label: Label {
|
text: Text {
|
||||||
text: "Button".to_string(),
|
value: "Button".to_string(),
|
||||||
font: asset_server.load("assets/fonts/FiraSans-Bold.ttf").unwrap(),
|
font: asset_server.load("assets/fonts/FiraSans-Bold.ttf").unwrap(),
|
||||||
style: TextStyle {
|
style: TextStyle {
|
||||||
font_size: 40.0,
|
font_size: 40.0,
|
||||||
|
Loading…
Reference in New Issue
Block a user