From 4d39a129e4da61679bc0fa4b42544d026edc5f7d Mon Sep 17 00:00:00 2001 From: Dmitry Stepanov Date: Thu, 20 Jun 2024 12:08:30 +0300 Subject: [PATCH] take collider global rotation into account in shape editing plugin - removed redundant code - fixed handles position for 2d colliders --- editor/src/plugins/collider/ball.rs | 56 +++--- editor/src/plugins/collider/ball2d.rs | 56 +++--- editor/src/plugins/collider/capsule.rs | 73 +++---- editor/src/plugins/collider/capsule2d.rs | 99 ++++------ editor/src/plugins/collider/cone.rs | 71 +++---- editor/src/plugins/collider/cuboid.rs | 133 ++++--------- editor/src/plugins/collider/cuboid2d.rs | 103 +++------- editor/src/plugins/collider/cylinder.rs | 76 +++----- editor/src/plugins/collider/dummy.rs | 13 +- editor/src/plugins/collider/mod.rs | 224 +++++++++------------- editor/src/plugins/collider/segment.rs | 46 ++--- editor/src/plugins/collider/segment2d.rs | 59 ++---- editor/src/plugins/collider/triangle.rs | 51 ++--- editor/src/plugins/collider/triangle2d.rs | 51 ++--- fyrox-math/src/lib.rs | 2 +- 15 files changed, 400 insertions(+), 713 deletions(-) diff --git a/editor/src/plugins/collider/ball.rs b/editor/src/plugins/collider/ball.rs index d1df21483..d18693c9f 100644 --- a/editor/src/plugins/collider/ball.rs +++ b/editor/src/plugins/collider/ball.rs @@ -1,15 +1,11 @@ use crate::{ fyrox::{ core::{algebra::Vector3, pool::Handle}, - scene::{ - collider::{BallShape, ColliderShape}, - node::Node, - Scene, - }, + scene::{collider::ColliderShape, node::Node, Scene}, }, plugins::collider::{ - make_handle, set_node_position, try_get_collider_shape, try_get_collider_shape_mut, - ShapeGizmoTrait, ShapeHandleValue, + make_handle, try_get_collider_shape, try_get_collider_shape_mut, ShapeGizmoTrait, + ShapeHandleValue, }, }; @@ -18,16 +14,9 @@ pub struct BallShapeGizmo { } impl BallShapeGizmo { - pub fn new( - ball: &BallShape, - center: Vector3, - side: Vector3, - root: Handle, - visible: bool, - scene: &mut Scene, - ) -> Self { + pub fn new(root: Handle, visible: bool, scene: &mut Scene) -> Self { Self { - radius_handle: make_handle(scene, center + side.scale(ball.radius), root, visible), + radius_handle: make_handle(scene, root, visible), } } } @@ -37,6 +26,23 @@ impl ShapeGizmoTrait for BallShapeGizmo { func(self.radius_handle) } + fn handle_local_position( + &self, + handle: Handle, + collider: Handle, + scene: &Scene, + ) -> Option> { + let Some(ColliderShape::Ball(ball)) = try_get_collider_shape(collider, scene) else { + return None; + }; + + if handle == self.radius_handle { + Some(Vector3::new(ball.radius, 0.0, 0.0)) + } else { + None + } + } + fn handle_major_axis( &self, handle: Handle, @@ -50,24 +56,6 @@ impl ShapeGizmoTrait for BallShapeGizmo { } } - fn try_sync_to_collider( - &self, - collider: Handle, - center: Vector3, - side: Vector3, - _up: Vector3, - _look: Vector3, - scene: &mut Scene, - ) -> bool { - let Some(ColliderShape::Ball(ball)) = try_get_collider_shape(collider, scene) else { - return false; - }; - - set_node_position(self.radius_handle, center + side.scale(ball.radius), scene); - - true - } - fn value_by_handle( &self, handle: Handle, diff --git a/editor/src/plugins/collider/ball2d.rs b/editor/src/plugins/collider/ball2d.rs index 90025595c..9ee76db1b 100644 --- a/editor/src/plugins/collider/ball2d.rs +++ b/editor/src/plugins/collider/ball2d.rs @@ -1,15 +1,11 @@ use crate::{ fyrox::{ core::{algebra::Vector3, pool::Handle}, - scene::{ - dim2::collider::{BallShape, ColliderShape}, - node::Node, - Scene, - }, + scene::{dim2::collider::ColliderShape, node::Node, Scene}, }, plugins::collider::{ - make_handle, set_node_position, try_get_collider_shape_2d, try_get_collider_shape_mut_2d, - ShapeGizmoTrait, ShapeHandleValue, + make_handle, try_get_collider_shape_2d, try_get_collider_shape_mut_2d, ShapeGizmoTrait, + ShapeHandleValue, }, }; @@ -18,16 +14,9 @@ pub struct Ball2DShapeGizmo { } impl Ball2DShapeGizmo { - pub fn new( - ball: &BallShape, - center: Vector3, - side: Vector3, - root: Handle, - visible: bool, - scene: &mut Scene, - ) -> Self { + pub fn new(root: Handle, visible: bool, scene: &mut Scene) -> Self { Self { - radius_handle: make_handle(scene, center + side.scale(ball.radius), root, visible), + radius_handle: make_handle(scene, root, visible), } } } @@ -37,6 +26,23 @@ impl ShapeGizmoTrait for Ball2DShapeGizmo { func(self.radius_handle) } + fn handle_local_position( + &self, + handle: Handle, + collider: Handle, + scene: &Scene, + ) -> Option> { + let Some(ColliderShape::Ball(ball)) = try_get_collider_shape_2d(collider, scene) else { + return None; + }; + + if handle == self.radius_handle { + Some(Vector3::new(ball.radius, 0.0, 0.0)) + } else { + None + } + } + fn handle_major_axis( &self, handle: Handle, @@ -50,24 +56,6 @@ impl ShapeGizmoTrait for Ball2DShapeGizmo { } } - fn try_sync_to_collider( - &self, - collider: Handle, - center: Vector3, - side: Vector3, - _up: Vector3, - _look: Vector3, - scene: &mut Scene, - ) -> bool { - let Some(ColliderShape::Ball(ball)) = try_get_collider_shape_2d(collider, scene) else { - return false; - }; - - set_node_position(self.radius_handle, center + side.scale(ball.radius), scene); - - true - } - fn value_by_handle( &self, handle: Handle, diff --git a/editor/src/plugins/collider/capsule.rs b/editor/src/plugins/collider/capsule.rs index 3900408ff..8d01d7e0c 100644 --- a/editor/src/plugins/collider/capsule.rs +++ b/editor/src/plugins/collider/capsule.rs @@ -1,18 +1,13 @@ use crate::{ fyrox::{ - core::{algebra::Vector3, pool::Handle}, - scene::{ - collider::{CapsuleShape, ColliderShape}, - node::Node, - Scene, - }, + core::{algebra::Vector3, math, pool::Handle}, + scene::{collider::ColliderShape, node::Node, Scene}, }, plugins::collider::{ - make_handle, set_node_position, try_get_collider_shape, try_get_collider_shape_mut, - ShapeGizmoTrait, ShapeHandleValue, + make_handle, try_get_collider_shape, try_get_collider_shape_mut, ShapeGizmoTrait, + ShapeHandleValue, }, }; -use fyrox::core::math; pub struct CapsuleShapeGizmo { radius_handle: Handle, @@ -21,18 +16,11 @@ pub struct CapsuleShapeGizmo { } impl CapsuleShapeGizmo { - pub fn new( - capsule: &CapsuleShape, - center: Vector3, - side: Vector3, - visible: bool, - root: Handle, - scene: &mut Scene, - ) -> Self { + pub fn new(visible: bool, root: Handle, scene: &mut Scene) -> Self { Self { - radius_handle: make_handle(scene, center + side.scale(capsule.radius), root, visible), - begin_handle: make_handle(scene, center + capsule.begin, root, visible), - end_handle: make_handle(scene, center + capsule.end, root, visible), + radius_handle: make_handle(scene, root, visible), + begin_handle: make_handle(scene, root, visible), + end_handle: make_handle(scene, root, visible), } } } @@ -44,7 +32,7 @@ impl ShapeGizmoTrait for CapsuleShapeGizmo { } } - fn handle_major_axis( + fn handle_local_position( &self, handle: Handle, collider: Handle, @@ -55,37 +43,38 @@ impl ShapeGizmoTrait for CapsuleShapeGizmo { }; if handle == self.radius_handle { - Some( - math::get_arbitrary_line_perpendicular(capsule.begin, capsule.end) - .unwrap_or_else(Vector3::x), - ) + let perp = math::get_arbitrary_line_perpendicular(capsule.begin, capsule.end) + .unwrap_or_else(Vector3::x) + .scale(capsule.radius); + + Some(capsule.begin + perp) + } else if handle == self.begin_handle { + Some(capsule.begin) + } else if handle == self.end_handle { + Some(capsule.end) } else { None } } - fn try_sync_to_collider( + fn handle_major_axis( &self, + handle: Handle, collider: Handle, - center: Vector3, - _side: Vector3, - _up: Vector3, - _look: Vector3, - scene: &mut Scene, - ) -> bool { + scene: &Scene, + ) -> Option> { let Some(ColliderShape::Capsule(capsule)) = try_get_collider_shape(collider, scene) else { - return false; + return None; }; - let perp = math::get_arbitrary_line_perpendicular(capsule.begin, capsule.end) - .unwrap_or_else(Vector3::x) - .scale(capsule.radius); - - set_node_position(self.radius_handle, center + capsule.begin + perp, scene); - set_node_position(self.begin_handle, center + capsule.begin, scene); - set_node_position(self.end_handle, center + capsule.end, scene); - - true + if handle == self.radius_handle { + Some( + math::get_arbitrary_line_perpendicular(capsule.begin, capsule.end) + .unwrap_or_else(Vector3::x), + ) + } else { + None + } } fn value_by_handle( diff --git a/editor/src/plugins/collider/capsule2d.rs b/editor/src/plugins/collider/capsule2d.rs index 59528bcac..65fb985e2 100644 --- a/editor/src/plugins/collider/capsule2d.rs +++ b/editor/src/plugins/collider/capsule2d.rs @@ -1,18 +1,13 @@ use crate::{ fyrox::{ - core::{algebra::Vector3, pool::Handle}, - scene::{ - dim2::collider::{CapsuleShape, ColliderShape}, - node::Node, - Scene, - }, + core::{algebra::Vector3, math, pool::Handle}, + scene::{dim2::collider::ColliderShape, node::Node, Scene}, }, plugins::collider::{ - make_handle, set_node_position, try_get_collider_shape_2d, try_get_collider_shape_mut_2d, - ShapeGizmoTrait, ShapeHandleValue, + make_handle, try_get_collider_shape_2d, try_get_collider_shape_mut_2d, ShapeGizmoTrait, + ShapeHandleValue, }, }; -use fyrox::core::math; pub struct Capsule2DShapeGizmo { radius_handle: Handle, @@ -21,23 +16,11 @@ pub struct Capsule2DShapeGizmo { } impl Capsule2DShapeGizmo { - pub fn new( - capsule: &CapsuleShape, - center: Vector3, - side: Vector3, - visible: bool, - root: Handle, - scene: &mut Scene, - ) -> Self { + pub fn new(visible: bool, root: Handle, scene: &mut Scene) -> Self { Self { - radius_handle: make_handle(scene, center + side.scale(capsule.radius), root, visible), - begin_handle: make_handle( - scene, - center + capsule.begin.to_homogeneous(), - root, - visible, - ), - end_handle: make_handle(scene, center + capsule.end.to_homogeneous(), root, visible), + radius_handle: make_handle(scene, root, visible), + begin_handle: make_handle(scene, root, visible), + end_handle: make_handle(scene, root, visible), } } } @@ -49,7 +32,7 @@ impl ShapeGizmoTrait for Capsule2DShapeGizmo { } } - fn handle_major_axis( + fn handle_local_position( &self, handle: Handle, collider: Handle, @@ -61,55 +44,45 @@ impl ShapeGizmoTrait for Capsule2DShapeGizmo { }; if handle == self.radius_handle { - Some( - math::get_arbitrary_line_perpendicular( - capsule.begin.to_homogeneous(), - capsule.end.to_homogeneous(), - ) - .unwrap_or_else(Vector3::x), + let perp = math::get_arbitrary_line_perpendicular( + capsule.begin.to_homogeneous(), + capsule.end.to_homogeneous(), ) + .unwrap_or_else(Vector3::x) + .scale(capsule.radius); + + Some(capsule.begin.to_homogeneous() + perp) + } else if handle == self.begin_handle { + Some(capsule.begin.to_homogeneous()) + } else if handle == self.end_handle { + Some(capsule.end.to_homogeneous()) } else { None } } - fn try_sync_to_collider( + fn handle_major_axis( &self, + handle: Handle, collider: Handle, - center: Vector3, - _side: Vector3, - _up: Vector3, - _look: Vector3, - scene: &mut Scene, - ) -> bool { + scene: &Scene, + ) -> Option> { let Some(ColliderShape::Capsule(capsule)) = try_get_collider_shape_2d(collider, scene) else { - return false; + return None; }; - let perp = math::get_arbitrary_line_perpendicular( - capsule.begin.to_homogeneous(), - capsule.end.to_homogeneous(), - ) - .unwrap_or_else(Vector3::x) - .scale(capsule.radius); - set_node_position( - self.radius_handle, - center + capsule.begin.to_homogeneous() + perp, - scene, - ); - set_node_position( - self.begin_handle, - center + capsule.begin.to_homogeneous(), - scene, - ); - set_node_position( - self.end_handle, - center + capsule.end.to_homogeneous(), - scene, - ); - - true + if handle == self.radius_handle { + Some( + math::get_arbitrary_line_perpendicular( + capsule.begin.to_homogeneous(), + capsule.end.to_homogeneous(), + ) + .unwrap_or_else(Vector3::x), + ) + } else { + None + } } fn value_by_handle( diff --git a/editor/src/plugins/collider/cone.rs b/editor/src/plugins/collider/cone.rs index 5f65368a3..d12af28df 100644 --- a/editor/src/plugins/collider/cone.rs +++ b/editor/src/plugins/collider/cone.rs @@ -1,15 +1,11 @@ use crate::{ fyrox::{ core::{algebra::Vector3, pool::Handle}, - scene::{ - collider::{ColliderShape, ConeShape}, - node::Node, - Scene, - }, + scene::{collider::ColliderShape, node::Node, Scene}, }, plugins::collider::{ - make_handle, set_node_position, try_get_collider_shape, try_get_collider_shape_mut, - ShapeGizmoTrait, ShapeHandleValue, + make_handle, try_get_collider_shape, try_get_collider_shape_mut, ShapeGizmoTrait, + ShapeHandleValue, }, }; @@ -19,23 +15,10 @@ pub struct ConeShapeGizmo { } impl ConeShapeGizmo { - pub fn new( - cone: &ConeShape, - center: Vector3, - side: Vector3, - up: Vector3, - visible: bool, - root: Handle, - scene: &mut Scene, - ) -> Self { + pub fn new(visible: bool, root: Handle, scene: &mut Scene) -> Self { Self { - radius_handle: make_handle(scene, center + side.scale(cone.radius), root, visible), - half_height_handle: make_handle( - scene, - center + up.scale(cone.half_height), - root, - visible, - ), + radius_handle: make_handle(scene, root, visible), + half_height_handle: make_handle(scene, root, visible), } } } @@ -47,6 +30,25 @@ impl ShapeGizmoTrait for ConeShapeGizmo { } } + fn handle_local_position( + &self, + handle: Handle, + collider: Handle, + scene: &Scene, + ) -> Option> { + let Some(ColliderShape::Cone(cone)) = try_get_collider_shape(collider, scene) else { + return None; + }; + + if handle == self.radius_handle { + Some(Vector3::new(cone.radius, 0.0, 0.0)) + } else if handle == self.half_height_handle { + Some(Vector3::new(0.0, cone.half_height * 2.0, 0.0)) + } else { + None + } + } + fn handle_major_axis( &self, handle: Handle, @@ -62,29 +64,6 @@ impl ShapeGizmoTrait for ConeShapeGizmo { } } - fn try_sync_to_collider( - &self, - collider: Handle, - center: Vector3, - side: Vector3, - up: Vector3, - _look: Vector3, - scene: &mut Scene, - ) -> bool { - let Some(ColliderShape::Cone(cone)) = try_get_collider_shape(collider, scene) else { - return false; - }; - - set_node_position(self.radius_handle, center + side.scale(cone.radius), scene); - set_node_position( - self.half_height_handle, - center + up.scale(cone.half_height), - scene, - ); - - true - } - fn value_by_handle( &self, handle: Handle, diff --git a/editor/src/plugins/collider/cuboid.rs b/editor/src/plugins/collider/cuboid.rs index ac3c447a5..a0ec8b641 100644 --- a/editor/src/plugins/collider/cuboid.rs +++ b/editor/src/plugins/collider/cuboid.rs @@ -3,14 +3,12 @@ use crate::{ core::{algebra::Vector3, pool::Handle}, graph::SceneGraph, scene::{ - collider::{Collider, ColliderShape, CuboidShape}, + collider::{Collider, ColliderShape}, node::Node, Scene, }, }, - plugins::collider::{ - make_handle, set_node_position, try_get_collider_shape, ShapeGizmoTrait, ShapeHandleValue, - }, + plugins::collider::{make_handle, try_get_collider_shape, ShapeGizmoTrait, ShapeHandleValue}, }; pub struct CuboidShapeGizmo { @@ -23,53 +21,14 @@ pub struct CuboidShapeGizmo { } impl CuboidShapeGizmo { - pub fn new( - cuboid: &CuboidShape, - center: Vector3, - side: Vector3, - up: Vector3, - look: Vector3, - visible: bool, - root: Handle, - scene: &mut Scene, - ) -> Self { + pub fn new(visible: bool, root: Handle, scene: &mut Scene) -> Self { Self { - pos_x_handle: make_handle( - scene, - center + side.scale(cuboid.half_extents.x), - root, - visible, - ), - pos_y_handle: make_handle( - scene, - center + up.scale(cuboid.half_extents.y), - root, - visible, - ), - pos_z_handle: make_handle( - scene, - center + look.scale(cuboid.half_extents.z), - root, - visible, - ), - neg_x_handle: make_handle( - scene, - center - side.scale(cuboid.half_extents.x), - root, - visible, - ), - neg_y_handle: make_handle( - scene, - center - up.scale(cuboid.half_extents.y), - root, - visible, - ), - neg_z_handle: make_handle( - scene, - center - look.scale(cuboid.half_extents.z), - root, - visible, - ), + pos_x_handle: make_handle(scene, root, visible), + pos_y_handle: make_handle(scene, root, visible), + pos_z_handle: make_handle(scene, root, visible), + neg_x_handle: make_handle(scene, root, visible), + neg_y_handle: make_handle(scene, root, visible), + neg_z_handle: make_handle(scene, root, visible), } } } @@ -88,6 +47,33 @@ impl ShapeGizmoTrait for CuboidShapeGizmo { } } + fn handle_local_position( + &self, + handle: Handle, + collider: Handle, + scene: &Scene, + ) -> Option> { + let Some(ColliderShape::Cuboid(cuboid)) = try_get_collider_shape(collider, scene) else { + return None; + }; + + if handle == self.pos_x_handle { + Some(Vector3::new(cuboid.half_extents.x, 0.0, 0.0)) + } else if handle == self.pos_y_handle { + Some(Vector3::new(0.0, cuboid.half_extents.y, 0.0)) + } else if handle == self.pos_z_handle { + Some(Vector3::new(0.0, 0.0, cuboid.half_extents.z)) + } else if handle == self.neg_x_handle { + Some(Vector3::new(-cuboid.half_extents.x, 0.0, 0.0)) + } else if handle == self.neg_y_handle { + Some(Vector3::new(0.0, -cuboid.half_extents.y, 0.0)) + } else if handle == self.neg_z_handle { + Some(Vector3::new(0.0, 0.0, -cuboid.half_extents.z)) + } else { + None + } + } + fn handle_major_axis( &self, handle: Handle, @@ -111,53 +97,6 @@ impl ShapeGizmoTrait for CuboidShapeGizmo { } } - fn try_sync_to_collider( - &self, - collider: Handle, - center: Vector3, - side: Vector3, - up: Vector3, - look: Vector3, - scene: &mut Scene, - ) -> bool { - let Some(ColliderShape::Cuboid(cuboid)) = try_get_collider_shape(collider, scene) else { - return false; - }; - - set_node_position( - self.pos_x_handle, - center + side.scale(cuboid.half_extents.x), - scene, - ); - set_node_position( - self.pos_y_handle, - center + up.scale(cuboid.half_extents.y), - scene, - ); - set_node_position( - self.pos_z_handle, - center + look.scale(cuboid.half_extents.z), - scene, - ); - set_node_position( - self.neg_x_handle, - center - side.scale(cuboid.half_extents.x), - scene, - ); - set_node_position( - self.neg_y_handle, - center - up.scale(cuboid.half_extents.y), - scene, - ); - set_node_position( - self.neg_z_handle, - center - look.scale(cuboid.half_extents.z), - scene, - ); - - true - } - fn value_by_handle( &self, handle: Handle, diff --git a/editor/src/plugins/collider/cuboid2d.rs b/editor/src/plugins/collider/cuboid2d.rs index be7180508..4201bf05a 100644 --- a/editor/src/plugins/collider/cuboid2d.rs +++ b/editor/src/plugins/collider/cuboid2d.rs @@ -3,14 +3,13 @@ use crate::{ core::{algebra::Vector3, pool::Handle}, graph::SceneGraph, scene::{ - dim2::collider::{Collider, ColliderShape, CuboidShape}, + dim2::collider::{Collider, ColliderShape}, node::Node, Scene, }, }, plugins::collider::{ - make_handle, set_node_position, try_get_collider_shape_2d, ShapeGizmoTrait, - ShapeHandleValue, + make_handle, try_get_collider_shape_2d, ShapeGizmoTrait, ShapeHandleValue, }, }; @@ -22,40 +21,12 @@ pub struct Cuboid2DShapeGizmo { } impl Cuboid2DShapeGizmo { - pub fn new( - cuboid: &CuboidShape, - center: Vector3, - side: Vector3, - up: Vector3, - visible: bool, - root: Handle, - scene: &mut Scene, - ) -> Self { + pub fn new(visible: bool, root: Handle, scene: &mut Scene) -> Self { Self { - pos_x_handle: make_handle( - scene, - center + side.scale(cuboid.half_extents.x), - root, - visible, - ), - pos_y_handle: make_handle( - scene, - center + up.scale(cuboid.half_extents.y), - root, - visible, - ), - neg_x_handle: make_handle( - scene, - center - side.scale(cuboid.half_extents.x), - root, - visible, - ), - neg_y_handle: make_handle( - scene, - center - up.scale(cuboid.half_extents.y), - root, - visible, - ), + pos_x_handle: make_handle(scene, root, visible), + pos_y_handle: make_handle(scene, root, visible), + neg_x_handle: make_handle(scene, root, visible), + neg_y_handle: make_handle(scene, root, visible), } } } @@ -72,6 +43,29 @@ impl ShapeGizmoTrait for Cuboid2DShapeGizmo { } } + fn handle_local_position( + &self, + handle: Handle, + collider: Handle, + scene: &Scene, + ) -> Option> { + let Some(ColliderShape::Cuboid(cuboid)) = try_get_collider_shape_2d(collider, scene) else { + return None; + }; + + if handle == self.pos_x_handle { + Some(Vector3::new(cuboid.half_extents.x, 0.0, 0.0)) + } else if handle == self.pos_y_handle { + Some(Vector3::new(0.0, cuboid.half_extents.y, 0.0)) + } else if handle == self.neg_x_handle { + Some(Vector3::new(-cuboid.half_extents.x, 0.0, 0.0)) + } else if handle == self.neg_y_handle { + Some(Vector3::new(0.0, -cuboid.half_extents.y, 0.0)) + } else { + None + } + } + fn handle_major_axis( &self, handle: Handle, @@ -91,43 +85,6 @@ impl ShapeGizmoTrait for Cuboid2DShapeGizmo { } } - fn try_sync_to_collider( - &self, - collider: Handle, - center: Vector3, - side: Vector3, - up: Vector3, - _look: Vector3, - scene: &mut Scene, - ) -> bool { - let Some(ColliderShape::Cuboid(cuboid)) = try_get_collider_shape_2d(collider, scene) else { - return false; - }; - - set_node_position( - self.pos_x_handle, - center + side.scale(cuboid.half_extents.x), - scene, - ); - set_node_position( - self.pos_y_handle, - center + up.scale(cuboid.half_extents.y), - scene, - ); - set_node_position( - self.neg_x_handle, - center - side.scale(cuboid.half_extents.x), - scene, - ); - set_node_position( - self.neg_y_handle, - center - up.scale(cuboid.half_extents.y), - scene, - ); - - true - } - fn value_by_handle( &self, handle: Handle, diff --git a/editor/src/plugins/collider/cylinder.rs b/editor/src/plugins/collider/cylinder.rs index 1e4786324..f40862c32 100644 --- a/editor/src/plugins/collider/cylinder.rs +++ b/editor/src/plugins/collider/cylinder.rs @@ -1,15 +1,11 @@ use crate::{ fyrox::{ core::{algebra::Vector3, pool::Handle}, - scene::{ - collider::{ColliderShape, CylinderShape}, - node::Node, - Scene, - }, + scene::{collider::ColliderShape, node::Node, Scene}, }, plugins::collider::{ - make_handle, set_node_position, try_get_collider_shape, try_get_collider_shape_mut, - ShapeGizmoTrait, ShapeHandleValue, + make_handle, try_get_collider_shape, try_get_collider_shape_mut, ShapeGizmoTrait, + ShapeHandleValue, }, }; @@ -19,23 +15,10 @@ pub struct CylinderShapeGizmo { } impl CylinderShapeGizmo { - pub fn new( - cylinder: &CylinderShape, - center: Vector3, - side: Vector3, - up: Vector3, - visible: bool, - root: Handle, - scene: &mut Scene, - ) -> Self { + pub fn new(visible: bool, root: Handle, scene: &mut Scene) -> Self { Self { - radius_handle: make_handle(scene, center + side.scale(cylinder.radius), root, visible), - half_height_handle: make_handle( - scene, - center + up.scale(cylinder.half_height), - root, - visible, - ), + radius_handle: make_handle(scene, root, visible), + half_height_handle: make_handle(scene, root, visible), } } } @@ -47,6 +30,25 @@ impl ShapeGizmoTrait for CylinderShapeGizmo { } } + fn handle_local_position( + &self, + handle: Handle, + collider: Handle, + scene: &Scene, + ) -> Option> { + let Some(ColliderShape::Cone(cone)) = try_get_collider_shape(collider, scene) else { + return None; + }; + + if handle == self.radius_handle { + Some(Vector3::new(cone.radius, 0.0, 0.0)) + } else if handle == self.half_height_handle { + Some(Vector3::new(0.0, cone.half_height * 2.0, 0.0)) + } else { + None + } + } + fn handle_major_axis( &self, handle: Handle, @@ -62,34 +64,6 @@ impl ShapeGizmoTrait for CylinderShapeGizmo { } } - fn try_sync_to_collider( - &self, - collider: Handle, - center: Vector3, - side: Vector3, - up: Vector3, - _look: Vector3, - scene: &mut Scene, - ) -> bool { - let Some(ColliderShape::Cylinder(cylinder)) = try_get_collider_shape(collider, scene) - else { - return false; - }; - - set_node_position( - self.radius_handle, - center + side.scale(cylinder.radius), - scene, - ); - set_node_position( - self.half_height_handle, - center + up.scale(cylinder.half_height), - scene, - ); - - true - } - fn value_by_handle( &self, handle: Handle, diff --git a/editor/src/plugins/collider/dummy.rs b/editor/src/plugins/collider/dummy.rs index 0f7ca4605..a00663f8a 100644 --- a/editor/src/plugins/collider/dummy.rs +++ b/editor/src/plugins/collider/dummy.rs @@ -11,16 +11,13 @@ pub struct DummyShapeGizmo; impl ShapeGizmoTrait for DummyShapeGizmo { fn for_each_handle(&self, _func: &mut dyn FnMut(Handle)) {} - fn try_sync_to_collider( + fn handle_local_position( &self, + _handle: Handle, _collider: Handle, - _center: Vector3, - _side: Vector3, - _up: Vector3, - _look: Vector3, - _scene: &mut Scene, - ) -> bool { - false + _scene: &Scene, + ) -> Option> { + None } fn value_by_handle( diff --git a/editor/src/plugins/collider/mod.rs b/editor/src/plugins/collider/mod.rs index 6168c7f12..2de548b7f 100644 --- a/editor/src/plugins/collider/mod.rs +++ b/editor/src/plugins/collider/mod.rs @@ -20,9 +20,9 @@ use crate::{ fyrox::{ asset::untyped::ResourceKind, core::{ - algebra::{Vector2, Vector3}, + algebra::{UnitQuaternion, Vector2, Vector3}, color::Color, - math::plane::Plane, + math::{plane::Plane, Matrix4Ext}, pool::Handle, reflect::Reflect, type_traits::prelude::*, @@ -37,12 +37,12 @@ use crate::{ }, scene::{ base::BaseBuilder, collider::Collider, collider::ColliderShape, dim2, node::Node, - sprite::SpriteBuilder, transform::TransformBuilder, Scene, + sprite::SpriteBuilder, Scene, }, }, interaction::{ - gizmo::move_gizmo::MoveGizmo, make_interaction_mode_button, plane::PlaneKind, - InteractionMode, + calculate_gizmo_distance_scaling, gizmo::move_gizmo::MoveGizmo, + make_interaction_mode_button, plane::PlaneKind, InteractionMode, }, load_texture, message::MessageSender, @@ -59,12 +59,6 @@ use crate::{ Editor, Message, }; -fn set_node_position(handle: Handle, position: Vector3, scene: &mut Scene) { - scene.graph[handle] - .local_transform_mut() - .set_position(position); -} - fn try_get_collider_shape(collider: Handle, scene: &Scene) -> Option { scene .graph @@ -105,6 +99,13 @@ fn try_get_collider_shape_mut_2d( trait ShapeGizmoTrait { fn for_each_handle(&self, func: &mut dyn FnMut(Handle)); + fn handle_local_position( + &self, + handle: Handle, + collider: Handle, + scene: &Scene, + ) -> Option>; + fn handle_major_axis( &self, _handle: Handle, @@ -114,16 +115,6 @@ trait ShapeGizmoTrait { None } - fn try_sync_to_collider( - &self, - collider: Handle, - center: Vector3, - side: Vector3, - up: Vector3, - look: Vector3, - scene: &mut Scene, - ) -> bool; - fn value_by_handle( &self, handle: Handle, @@ -169,14 +160,31 @@ trait ShapeGizmoTrait { scene.graph[handle].set_visibility(visibility); }) } + + fn try_sync_to_collider(&self, collider: Handle, scene: &mut Scene) -> bool { + let mut is_ok = true; + let transform = scene.graph[collider].global_transform(); + self.for_each_handle(&mut |handle| { + if let Some(local_position) = self.handle_local_position(handle, collider, scene) { + scene.graph[handle] + .local_transform_mut() + .set_position(transform.transform_point(&local_position.into()).coords) + .set_rotation(UnitQuaternion::from_matrix_eps( + &transform.basis(), + f32::EPSILON, + 16, + Default::default(), + )); + } else { + is_ok = false; + } + }); + is_ok + } } fn make_shape_gizmo( collider: Handle, - center: Vector3, - side: Vector3, - up: Vector3, - look: Vector3, scene: &mut Scene, root: Handle, visible: bool, @@ -184,27 +192,13 @@ fn make_shape_gizmo( if let Some(collider) = scene.graph.try_get_of_type::(collider) { let shape = collider.shape().clone(); match shape { - ColliderShape::Ball(ball) => Box::new(BallShapeGizmo::new( - &ball, center, side, root, visible, scene, - )), - ColliderShape::Cylinder(cylinder) => Box::new(CylinderShapeGizmo::new( - &cylinder, center, side, up, visible, root, scene, - )), - ColliderShape::Cone(cone) => Box::new(ConeShapeGizmo::new( - &cone, center, side, up, visible, root, scene, - )), - ColliderShape::Cuboid(cuboid) => Box::new(CuboidShapeGizmo::new( - &cuboid, center, side, up, look, visible, root, scene, - )), - ColliderShape::Capsule(capsule) => Box::new(CapsuleShapeGizmo::new( - &capsule, center, side, visible, root, scene, - )), - ColliderShape::Segment(segment) => Box::new(SegmentShapeGizmo::new( - &segment, center, root, visible, scene, - )), - ColliderShape::Triangle(triangle) => Box::new(TriangleShapeGizmo::new( - &triangle, center, root, visible, scene, - )), + ColliderShape::Ball(_) => Box::new(BallShapeGizmo::new(root, visible, scene)), + ColliderShape::Cylinder(_) => Box::new(CylinderShapeGizmo::new(visible, root, scene)), + ColliderShape::Cone(_) => Box::new(ConeShapeGizmo::new(visible, root, scene)), + ColliderShape::Cuboid(_) => Box::new(CuboidShapeGizmo::new(visible, root, scene)), + ColliderShape::Capsule(_) => Box::new(CapsuleShapeGizmo::new(visible, root, scene)), + ColliderShape::Segment(_) => Box::new(SegmentShapeGizmo::new(root, visible, scene)), + ColliderShape::Triangle(_) => Box::new(TriangleShapeGizmo::new(root, visible, scene)), ColliderShape::Trimesh(_) | ColliderShape::Heightfield(_) | ColliderShape::Polyhedron(_) => Box::new(DummyShapeGizmo), @@ -215,21 +209,21 @@ fn make_shape_gizmo( { let shape = collider.shape().clone(); match shape { - dim2::collider::ColliderShape::Ball(ball) => Box::new(Ball2DShapeGizmo::new( - &ball, center, side, root, visible, scene, - )), - dim2::collider::ColliderShape::Cuboid(cuboid) => Box::new(Cuboid2DShapeGizmo::new( - &cuboid, center, side, up, visible, root, scene, - )), - dim2::collider::ColliderShape::Capsule(capsule) => Box::new(Capsule2DShapeGizmo::new( - &capsule, center, side, visible, root, scene, - )), - dim2::collider::ColliderShape::Segment(segment) => Box::new(Segment2DShapeGizmo::new( - &segment, center, root, visible, scene, - )), - dim2::collider::ColliderShape::Triangle(triangle) => Box::new( - Triangle2DShapeGizmo::new(&triangle, center, root, visible, scene), - ), + dim2::collider::ColliderShape::Ball(_) => { + Box::new(Ball2DShapeGizmo::new(root, visible, scene)) + } + dim2::collider::ColliderShape::Cuboid(_) => { + Box::new(Cuboid2DShapeGizmo::new(visible, root, scene)) + } + dim2::collider::ColliderShape::Capsule(_) => { + Box::new(Capsule2DShapeGizmo::new(visible, root, scene)) + } + dim2::collider::ColliderShape::Segment(_) => { + Box::new(Segment2DShapeGizmo::new(root, visible, scene)) + } + dim2::collider::ColliderShape::Triangle(_) => { + Box::new(Triangle2DShapeGizmo::new(root, visible, scene)) + } dim2::collider::ColliderShape::Trimesh(_) | dim2::collider::ColliderShape::Heightfield(_) => Box::new(DummyShapeGizmo), } @@ -248,12 +242,7 @@ lazy_static! { }; } -fn make_handle( - scene: &mut Scene, - position: Vector3, - root: Handle, - visible: bool, -) -> Handle { +fn make_handle(scene: &mut Scene, root: Handle, visible: bool) -> Handle { let mut material = Material::from_shader(GIZMO_SHADER.clone(), None); material @@ -263,19 +252,11 @@ fn make_handle( ) .unwrap(); - let handle = SpriteBuilder::new( - BaseBuilder::new() - .with_local_transform( - TransformBuilder::new() - .with_local_position(position) - .build(), - ) - .with_visibility(visible), - ) - .with_material(MaterialResource::new_ok(ResourceKind::Embedded, material)) - .with_size(0.05) - .with_color(Color::MAROON) - .build(&mut scene.graph); + let handle = SpriteBuilder::new(BaseBuilder::new().with_visibility(visible)) + .with_material(MaterialResource::new_ok(ResourceKind::Embedded, material)) + .with_size(0.05) + .with_color(Color::MAROON) + .build(&mut scene.graph); scene.graph.link_nodes(handle, root); @@ -555,7 +536,7 @@ impl InteractionMode for ColliderShapeInteractionMode { .unwrap() .into_vector(); - let offset = self.move_gizmo.calculate_offset( + let global_offset = self.move_gizmo.calculate_offset( &scene.graph, game_scene.camera_controller.camera, mouse_offset, @@ -564,9 +545,15 @@ impl InteractionMode for ColliderShapeInteractionMode { plane_kind, ); + let local_offset = scene.graph[self.collider] + .global_transform() + .try_inverse() + .unwrap_or_default() + .transform_vector(&global_offset); + self.shape_gizmo.set_value_by_handle( drag_context.handle, - ShapeHandleValue::Vector(value + offset), + ShapeHandleValue::Vector(value + local_offset), self.collider, scene, drag_context.initial_collider_local_position, @@ -590,38 +577,9 @@ impl InteractionMode for ColliderShapeInteractionMode { let scene = &mut engine.scenes[game_scene.scene]; - let Some(collider) = scene.graph.try_get(self.collider) else { - return; - }; - - let center = collider.global_position(); - let side = collider - .side_vector() - .try_normalize(f32::EPSILON) - .unwrap_or_default(); - let up = collider - .up_vector() - .try_normalize(f32::EPSILON) - .unwrap_or_default(); - let look = collider - .look_vector() - .try_normalize(f32::EPSILON) - .unwrap_or_default(); - - if !self - .shape_gizmo - .try_sync_to_collider(self.collider, center, side, up, look, scene) - { - let new_gizmo = make_shape_gizmo( - self.collider, - center, - side, - up, - look, - scene, - game_scene.editor_objects_root, - true, - ); + if !self.shape_gizmo.try_sync_to_collider(self.collider, scene) { + let new_gizmo = + make_shape_gizmo(self.collider, scene, game_scene.editor_objects_root, true); let old_gizmo = std::mem::replace(&mut self.shape_gizmo, new_gizmo); @@ -632,9 +590,23 @@ impl InteractionMode for ColliderShapeInteractionMode { &mut scene.graph, self.shape_gizmo.is_vector_handle(self.selected_handle), ); - if let Some(selected_handle) = scene.graph.try_get(self.selected_handle) { - let position = selected_handle.global_position(); - self.move_gizmo.set_position(scene, position) + let scale = calculate_gizmo_distance_scaling( + &scene.graph, + game_scene.camera_controller.camera, + self.move_gizmo.origin, + ); + if let Some(handle_local_position) = + self.shape_gizmo + .handle_local_position(self.selected_handle, self.collider, scene) + { + let transform = scene.graph[self.collider].global_transform(); + let position = transform + .transform_point(&handle_local_position.into()) + .coords; + self.move_gizmo + .transform(&mut scene.graph) + .set_position(position) + .set_scale(scale); } } @@ -697,26 +669,8 @@ impl EditorPlugin for ColliderShapePlugin { continue; } - let center = collider.global_position(); - let side = collider - .side_vector() - .try_normalize(f32::EPSILON) - .unwrap_or_default(); - let up = collider - .up_vector() - .try_normalize(f32::EPSILON) - .unwrap_or_default(); - let look = collider - .look_vector() - .try_normalize(f32::EPSILON) - .unwrap_or_default(); - let shape_gizmo = make_shape_gizmo( *node_handle, - center, - side, - up, - look, scene, game_scene.editor_objects_root, false, diff --git a/editor/src/plugins/collider/segment.rs b/editor/src/plugins/collider/segment.rs index c65a5b318..b09d4eb7b 100644 --- a/editor/src/plugins/collider/segment.rs +++ b/editor/src/plugins/collider/segment.rs @@ -1,15 +1,11 @@ use crate::{ fyrox::{ core::{algebra::Vector3, pool::Handle}, - scene::{ - collider::{ColliderShape, SegmentShape}, - node::Node, - Scene, - }, + scene::{collider::ColliderShape, node::Node, Scene}, }, plugins::collider::{ - make_handle, set_node_position, try_get_collider_shape, try_get_collider_shape_mut, - ShapeGizmoTrait, ShapeHandleValue, + make_handle, try_get_collider_shape, try_get_collider_shape_mut, ShapeGizmoTrait, + ShapeHandleValue, }, }; @@ -19,16 +15,10 @@ pub struct SegmentShapeGizmo { } impl SegmentShapeGizmo { - pub fn new( - segment: &SegmentShape, - center: Vector3, - root: Handle, - visible: bool, - scene: &mut Scene, - ) -> Self { + pub fn new(root: Handle, visible: bool, scene: &mut Scene) -> Self { Self { - begin_handle: make_handle(scene, center + segment.begin, root, visible), - end_handle: make_handle(scene, center + segment.end, root, visible), + begin_handle: make_handle(scene, root, visible), + end_handle: make_handle(scene, root, visible), } } } @@ -40,23 +30,23 @@ impl ShapeGizmoTrait for SegmentShapeGizmo { } } - fn try_sync_to_collider( + fn handle_local_position( &self, + handle: Handle, collider: Handle, - center: Vector3, - _side: Vector3, - _up: Vector3, - _look: Vector3, - scene: &mut Scene, - ) -> bool { + scene: &Scene, + ) -> Option> { let Some(ColliderShape::Segment(segment)) = try_get_collider_shape(collider, scene) else { - return false; + return None; }; - set_node_position(self.begin_handle, center + segment.begin, scene); - set_node_position(self.end_handle, center + segment.end, scene); - - true + if handle == self.begin_handle { + Some(segment.begin) + } else if handle == self.end_handle { + Some(segment.end) + } else { + None + } } fn value_by_handle( diff --git a/editor/src/plugins/collider/segment2d.rs b/editor/src/plugins/collider/segment2d.rs index c5aa42423..84794d178 100644 --- a/editor/src/plugins/collider/segment2d.rs +++ b/editor/src/plugins/collider/segment2d.rs @@ -1,15 +1,11 @@ use crate::{ fyrox::{ core::{algebra::Vector3, pool::Handle}, - scene::{ - dim2::collider::{ColliderShape, SegmentShape}, - node::Node, - Scene, - }, + scene::{dim2::collider::ColliderShape, node::Node, Scene}, }, plugins::collider::{ - make_handle, set_node_position, try_get_collider_shape_2d, try_get_collider_shape_mut_2d, - ShapeGizmoTrait, ShapeHandleValue, + make_handle, try_get_collider_shape_2d, try_get_collider_shape_mut_2d, ShapeGizmoTrait, + ShapeHandleValue, }, }; @@ -19,21 +15,10 @@ pub struct Segment2DShapeGizmo { } impl Segment2DShapeGizmo { - pub fn new( - segment: &SegmentShape, - center: Vector3, - root: Handle, - visible: bool, - scene: &mut Scene, - ) -> Self { + pub fn new(root: Handle, visible: bool, scene: &mut Scene) -> Self { Self { - begin_handle: make_handle( - scene, - center + segment.begin.to_homogeneous(), - root, - visible, - ), - end_handle: make_handle(scene, center + segment.end.to_homogeneous(), root, visible), + begin_handle: make_handle(scene, root, visible), + end_handle: make_handle(scene, root, visible), } } } @@ -45,32 +30,24 @@ impl ShapeGizmoTrait for Segment2DShapeGizmo { } } - fn try_sync_to_collider( + fn handle_local_position( &self, + handle: Handle, collider: Handle, - center: Vector3, - _side: Vector3, - _up: Vector3, - _look: Vector3, - scene: &mut Scene, - ) -> bool { + scene: &Scene, + ) -> Option> { let Some(ColliderShape::Segment(segment)) = try_get_collider_shape_2d(collider, scene) else { - return false; + return None; }; - set_node_position( - self.begin_handle, - center + segment.begin.to_homogeneous(), - scene, - ); - set_node_position( - self.end_handle, - center + segment.end.to_homogeneous(), - scene, - ); - - true + if handle == self.begin_handle { + Some(segment.begin.to_homogeneous()) + } else if handle == self.end_handle { + Some(segment.end.to_homogeneous()) + } else { + None + } } fn value_by_handle( diff --git a/editor/src/plugins/collider/triangle.rs b/editor/src/plugins/collider/triangle.rs index 8a23d9812..8f451b61a 100644 --- a/editor/src/plugins/collider/triangle.rs +++ b/editor/src/plugins/collider/triangle.rs @@ -1,15 +1,11 @@ use crate::{ fyrox::{ core::{algebra::Vector3, pool::Handle}, - scene::{ - collider::{ColliderShape, TriangleShape}, - node::Node, - Scene, - }, + scene::{collider::ColliderShape, node::Node, Scene}, }, plugins::collider::{ - make_handle, set_node_position, try_get_collider_shape, try_get_collider_shape_mut, - ShapeGizmoTrait, ShapeHandleValue, + make_handle, try_get_collider_shape, try_get_collider_shape_mut, ShapeGizmoTrait, + ShapeHandleValue, }, }; @@ -20,17 +16,11 @@ pub struct TriangleShapeGizmo { } impl TriangleShapeGizmo { - pub fn new( - triangle: &TriangleShape, - center: Vector3, - root: Handle, - visible: bool, - scene: &mut Scene, - ) -> Self { + pub fn new(root: Handle, visible: bool, scene: &mut Scene) -> Self { Self { - a_handle: make_handle(scene, center + triangle.a, root, visible), - b_handle: make_handle(scene, center + triangle.b, root, visible), - c_handle: make_handle(scene, center + triangle.c, root, visible), + a_handle: make_handle(scene, root, visible), + b_handle: make_handle(scene, root, visible), + c_handle: make_handle(scene, root, visible), } } } @@ -42,25 +32,26 @@ impl ShapeGizmoTrait for TriangleShapeGizmo { } } - fn try_sync_to_collider( + fn handle_local_position( &self, + handle: Handle, collider: Handle, - center: Vector3, - _side: Vector3, - _up: Vector3, - _look: Vector3, - scene: &mut Scene, - ) -> bool { + scene: &Scene, + ) -> Option> { let Some(ColliderShape::Triangle(triangle)) = try_get_collider_shape(collider, scene) else { - return false; + return None; }; - set_node_position(self.a_handle, center + triangle.a, scene); - set_node_position(self.b_handle, center + triangle.b, scene); - set_node_position(self.c_handle, center + triangle.c, scene); - - true + if handle == self.a_handle { + Some(triangle.a) + } else if handle == self.b_handle { + Some(triangle.b) + } else if handle == self.c_handle { + Some(triangle.c) + } else { + None + } } fn value_by_handle( diff --git a/editor/src/plugins/collider/triangle2d.rs b/editor/src/plugins/collider/triangle2d.rs index 09372ce30..e7b2319f7 100644 --- a/editor/src/plugins/collider/triangle2d.rs +++ b/editor/src/plugins/collider/triangle2d.rs @@ -1,15 +1,11 @@ use crate::{ fyrox::{ core::{algebra::Vector3, pool::Handle}, - scene::{ - dim2::collider::{ColliderShape, TriangleShape}, - node::Node, - Scene, - }, + scene::{dim2::collider::ColliderShape, node::Node, Scene}, }, plugins::collider::{ - make_handle, set_node_position, try_get_collider_shape_2d, try_get_collider_shape_mut_2d, - ShapeGizmoTrait, ShapeHandleValue, + make_handle, try_get_collider_shape_2d, try_get_collider_shape_mut_2d, ShapeGizmoTrait, + ShapeHandleValue, }, }; @@ -20,17 +16,11 @@ pub struct Triangle2DShapeGizmo { } impl Triangle2DShapeGizmo { - pub fn new( - triangle: &TriangleShape, - center: Vector3, - root: Handle, - visible: bool, - scene: &mut Scene, - ) -> Self { + pub fn new(root: Handle, visible: bool, scene: &mut Scene) -> Self { Self { - a_handle: make_handle(scene, center + triangle.a.to_homogeneous(), root, visible), - b_handle: make_handle(scene, center + triangle.b.to_homogeneous(), root, visible), - c_handle: make_handle(scene, center + triangle.c.to_homogeneous(), root, visible), + a_handle: make_handle(scene, root, visible), + b_handle: make_handle(scene, root, visible), + c_handle: make_handle(scene, root, visible), } } } @@ -42,25 +32,26 @@ impl ShapeGizmoTrait for Triangle2DShapeGizmo { } } - fn try_sync_to_collider( + fn handle_local_position( &self, + handle: Handle, collider: Handle, - center: Vector3, - _side: Vector3, - _up: Vector3, - _look: Vector3, - scene: &mut Scene, - ) -> bool { + scene: &Scene, + ) -> Option> { let Some(ColliderShape::Triangle(triangle)) = try_get_collider_shape_2d(collider, scene) else { - return false; + return None; }; - set_node_position(self.a_handle, center + triangle.a.to_homogeneous(), scene); - set_node_position(self.b_handle, center + triangle.b.to_homogeneous(), scene); - set_node_position(self.c_handle, center + triangle.c.to_homogeneous(), scene); - - true + if handle == self.a_handle { + Some(triangle.a.to_homogeneous()) + } else if handle == self.b_handle { + Some(triangle.b.to_homogeneous()) + } else if handle == self.c_handle { + Some(triangle.c.to_homogeneous()) + } else { + None + } } fn value_by_handle( diff --git a/fyrox-math/src/lib.rs b/fyrox-math/src/lib.rs index e57513a1f..2924ecc66 100644 --- a/fyrox-math/src/lib.rs +++ b/fyrox-math/src/lib.rs @@ -551,7 +551,7 @@ pub fn get_arbitrary_line_perpendicular( end: Vector3, ) -> Option> { let dir = (end - begin).try_normalize(f32::EPSILON)?; - for axis in [Vector3::x(), Vector3::y(), Vector3::z()] { + for axis in [Vector3::z(), Vector3::y(), Vector3::x()] { let perp = dir.cross(&axis); if perp.norm_squared().ne(&0.0) { return Some(perp);