use super::Component;
use crate::engine::ecs::ComponentId;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TransformGizmoAxis {
X,
Y,
Z,
}
impl TransformGizmoAxis {
pub fn unit_vec3(self) -> [f32; 3] {
match self {
TransformGizmoAxis::X => [1.0, 0.0, 0.0],
TransformGizmoAxis::Y => [0.0, 1.0, 0.0],
TransformGizmoAxis::Z => [0.0, 0.0, 1.0],
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct TransformGizmoTranslateComponent {
pub axis: TransformGizmoAxis,
}
impl TransformGizmoTranslateComponent {
pub fn new(axis: TransformGizmoAxis) -> Self {
Self { axis }
}
}
impl Component for TransformGizmoTranslateComponent {
fn name(&self) -> &'static str {
"transform_gizmo_translate"
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self
}
fn to_mms_ast(
&self,
_world: &crate::engine::ecs::World,
) -> crate::scripting::ast::ComponentExpression {
use crate::engine::ecs::component::ce_helpers::*;
ce_call("TransformGizmoTranslate", axis_ctor(self.axis), vec![])
}
}
fn axis_ctor(axis: TransformGizmoAxis) -> &'static str {
match axis {
TransformGizmoAxis::X => "x",
TransformGizmoAxis::Y => "y",
TransformGizmoAxis::Z => "z",
}
}
#[derive(Debug, Clone, Copy)]
pub struct TransformGizmoRotateComponent {
pub axis: TransformGizmoAxis,
}
impl TransformGizmoRotateComponent {
pub fn new(axis: TransformGizmoAxis) -> Self {
Self { axis }
}
}
impl Component for TransformGizmoRotateComponent {
fn name(&self) -> &'static str {
"transform_gizmo_rotate"
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self
}
fn to_mms_ast(
&self,
_world: &crate::engine::ecs::World,
) -> crate::scripting::ast::ComponentExpression {
use crate::engine::ecs::component::ce_helpers::*;
ce_call("TransformGizmoRotate", axis_ctor(self.axis), vec![])
}
}
#[derive(Debug, Clone, Copy)]
pub struct TransformGizmoScaleComponent {
pub axis: TransformGizmoAxis,
}
impl TransformGizmoScaleComponent {
pub fn new(axis: TransformGizmoAxis) -> Self {
Self { axis }
}
}
impl Component for TransformGizmoScaleComponent {
fn name(&self) -> &'static str {
"transform_gizmo_scale"
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self
}
fn to_mms_ast(
&self,
_world: &crate::engine::ecs::World,
) -> crate::scripting::ast::ComponentExpression {
use crate::engine::ecs::component::ce_helpers::*;
ce_call("TransformGizmoScale", axis_ctor(self.axis), vec![])
}
}
#[derive(Debug, Clone, Copy)]
pub struct TransformGizmoComponent {
pub scale: f32,
pub target_transform: Option<ComponentId>,
pub active_raycaster: Option<ComponentId>,
pub active_drag_slider_last_angle: f32,
pub active_drag_start_hit_point_world: Option<[f32; 3]>,
pub active_drag_start_target_translation: Option<[f32; 3]>,
pub visual_root: Option<ComponentId>,
pub debug_drag_plane_root: Option<ComponentId>,
component: Option<ComponentId>,
}
impl TransformGizmoComponent {
pub fn new() -> Self {
Self {
scale: 1.0,
target_transform: None,
active_raycaster: None,
active_drag_slider_last_angle: 0.0,
active_drag_start_hit_point_world: None,
active_drag_start_target_translation: None,
visual_root: None,
debug_drag_plane_root: None,
component: None,
}
}
pub fn with_scale(mut self, scale: f32) -> Self {
self.scale = scale;
self
}
pub fn translate() -> Self {
Self::new()
}
pub fn id(&self) -> Option<ComponentId> {
self.component
}
}
impl Component for TransformGizmoComponent {
fn set_id(&mut self, component: ComponentId) {
self.component = Some(component);
}
fn name(&self) -> &'static str {
"transform_gizmo"
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self
}
fn to_mms_ast(
&self,
_world: &crate::engine::ecs::World,
) -> crate::scripting::ast::ComponentExpression {
use crate::engine::ecs::component::ce_helpers::*;
ce("TransformGizmo").with_call("scale", vec![num(self.scale as f64)])
}
fn init(&mut self, emit: &mut dyn crate::engine::ecs::SignalEmitter, component: ComponentId) {
emit.push_intent_now(
component,
crate::engine::ecs::IntentValue::RegisterTransformGizmo {
component_ids: vec![component],
},
);
}
fn cleanup(
&mut self,
emit: &mut dyn crate::engine::ecs::SignalEmitter,
_component: ComponentId,
) {
if let Some(root) = self.visual_root.take() {
emit.push_intent_now(
root,
crate::engine::ecs::IntentValue::RemoveSubtree {
component_ids: vec![root],
},
);
}
if let Some(root) = self.debug_drag_plane_root.take() {
emit.push_intent_now(
root,
crate::engine::ecs::IntentValue::RemoveSubtree {
component_ids: vec![root],
},
);
}
}
}