rg3d/utils/
mod.rs

1#![warn(missing_docs)]
2
3//! Utilities module provides set of commonly used algorithms.
4
5pub mod astar;
6pub mod behavior;
7pub mod lightmap;
8pub mod log;
9pub mod navmesh;
10pub mod raw_mesh;
11pub mod uvgen;
12
13use crate::core::algebra::Vector2;
14use crate::{
15    event::{ElementState, ModifiersState, MouseScrollDelta, VirtualKeyCode, WindowEvent},
16    gui::{
17        draw,
18        message::{ButtonState, KeyCode, KeyboardModifiers, OsEvent},
19    },
20    resource::texture::Texture,
21};
22use std::hash::Hasher;
23use std::{any::Any, sync::Arc};
24
25/// Translated key code to rg3d-ui key code.
26pub fn translate_key(key: VirtualKeyCode) -> KeyCode {
27    match key {
28        VirtualKeyCode::Key1 => KeyCode::Key1,
29        VirtualKeyCode::Key2 => KeyCode::Key2,
30        VirtualKeyCode::Key3 => KeyCode::Key3,
31        VirtualKeyCode::Key4 => KeyCode::Key4,
32        VirtualKeyCode::Key5 => KeyCode::Key5,
33        VirtualKeyCode::Key6 => KeyCode::Key6,
34        VirtualKeyCode::Key7 => KeyCode::Key7,
35        VirtualKeyCode::Key8 => KeyCode::Key8,
36        VirtualKeyCode::Key9 => KeyCode::Key9,
37        VirtualKeyCode::Key0 => KeyCode::Key0,
38        VirtualKeyCode::A => KeyCode::A,
39        VirtualKeyCode::B => KeyCode::B,
40        VirtualKeyCode::C => KeyCode::C,
41        VirtualKeyCode::D => KeyCode::D,
42        VirtualKeyCode::E => KeyCode::E,
43        VirtualKeyCode::F => KeyCode::F,
44        VirtualKeyCode::G => KeyCode::G,
45        VirtualKeyCode::H => KeyCode::H,
46        VirtualKeyCode::I => KeyCode::I,
47        VirtualKeyCode::J => KeyCode::J,
48        VirtualKeyCode::K => KeyCode::K,
49        VirtualKeyCode::L => KeyCode::L,
50        VirtualKeyCode::M => KeyCode::M,
51        VirtualKeyCode::N => KeyCode::N,
52        VirtualKeyCode::O => KeyCode::O,
53        VirtualKeyCode::P => KeyCode::P,
54        VirtualKeyCode::Q => KeyCode::Q,
55        VirtualKeyCode::R => KeyCode::R,
56        VirtualKeyCode::S => KeyCode::S,
57        VirtualKeyCode::T => KeyCode::T,
58        VirtualKeyCode::U => KeyCode::U,
59        VirtualKeyCode::V => KeyCode::V,
60        VirtualKeyCode::W => KeyCode::W,
61        VirtualKeyCode::X => KeyCode::X,
62        VirtualKeyCode::Y => KeyCode::Y,
63        VirtualKeyCode::Z => KeyCode::Z,
64        VirtualKeyCode::Escape => KeyCode::Escape,
65        VirtualKeyCode::F1 => KeyCode::F1,
66        VirtualKeyCode::F2 => KeyCode::F2,
67        VirtualKeyCode::F3 => KeyCode::F3,
68        VirtualKeyCode::F4 => KeyCode::F4,
69        VirtualKeyCode::F5 => KeyCode::F5,
70        VirtualKeyCode::F6 => KeyCode::F6,
71        VirtualKeyCode::F7 => KeyCode::F7,
72        VirtualKeyCode::F8 => KeyCode::F8,
73        VirtualKeyCode::F9 => KeyCode::F9,
74        VirtualKeyCode::F10 => KeyCode::F10,
75        VirtualKeyCode::F11 => KeyCode::F11,
76        VirtualKeyCode::F12 => KeyCode::F12,
77        VirtualKeyCode::F13 => KeyCode::F13,
78        VirtualKeyCode::F14 => KeyCode::F14,
79        VirtualKeyCode::F15 => KeyCode::F15,
80        VirtualKeyCode::F16 => KeyCode::F16,
81        VirtualKeyCode::F17 => KeyCode::F17,
82        VirtualKeyCode::F18 => KeyCode::F18,
83        VirtualKeyCode::F19 => KeyCode::F19,
84        VirtualKeyCode::F20 => KeyCode::F20,
85        VirtualKeyCode::F21 => KeyCode::F21,
86        VirtualKeyCode::F22 => KeyCode::F22,
87        VirtualKeyCode::F23 => KeyCode::F23,
88        VirtualKeyCode::F24 => KeyCode::F24,
89        VirtualKeyCode::Snapshot => KeyCode::Snapshot,
90        VirtualKeyCode::Scroll => KeyCode::Scroll,
91        VirtualKeyCode::Pause => KeyCode::Pause,
92        VirtualKeyCode::Insert => KeyCode::Insert,
93        VirtualKeyCode::Home => KeyCode::Home,
94        VirtualKeyCode::Delete => KeyCode::Delete,
95        VirtualKeyCode::End => KeyCode::End,
96        VirtualKeyCode::PageDown => KeyCode::PageDown,
97        VirtualKeyCode::PageUp => KeyCode::PageUp,
98        VirtualKeyCode::Left => KeyCode::Left,
99        VirtualKeyCode::Up => KeyCode::Up,
100        VirtualKeyCode::Right => KeyCode::Right,
101        VirtualKeyCode::Down => KeyCode::Down,
102        VirtualKeyCode::Back => KeyCode::Backspace,
103        VirtualKeyCode::Return => KeyCode::Return,
104        VirtualKeyCode::Space => KeyCode::Space,
105        VirtualKeyCode::Compose => KeyCode::Compose,
106        VirtualKeyCode::Caret => KeyCode::Caret,
107        VirtualKeyCode::Numlock => KeyCode::Numlock,
108        VirtualKeyCode::Numpad0 => KeyCode::Numpad0,
109        VirtualKeyCode::Numpad1 => KeyCode::Numpad1,
110        VirtualKeyCode::Numpad2 => KeyCode::Numpad2,
111        VirtualKeyCode::Numpad3 => KeyCode::Numpad3,
112        VirtualKeyCode::Numpad4 => KeyCode::Numpad4,
113        VirtualKeyCode::Numpad5 => KeyCode::Numpad5,
114        VirtualKeyCode::Numpad6 => KeyCode::Numpad6,
115        VirtualKeyCode::Numpad7 => KeyCode::Numpad7,
116        VirtualKeyCode::Numpad8 => KeyCode::Numpad8,
117        VirtualKeyCode::Numpad9 => KeyCode::Numpad9,
118        VirtualKeyCode::AbntC1 => KeyCode::AbntC1,
119        VirtualKeyCode::AbntC2 => KeyCode::AbntC2,
120        VirtualKeyCode::NumpadAdd => KeyCode::NumpadAdd,
121        VirtualKeyCode::Apostrophe => KeyCode::Apostrophe,
122        VirtualKeyCode::Apps => KeyCode::Apps,
123        VirtualKeyCode::At => KeyCode::At,
124        VirtualKeyCode::Ax => KeyCode::Ax,
125        VirtualKeyCode::Backslash => KeyCode::Backslash,
126        VirtualKeyCode::Calculator => KeyCode::Calculator,
127        VirtualKeyCode::Capital => KeyCode::Capital,
128        VirtualKeyCode::Colon => KeyCode::Colon,
129        VirtualKeyCode::Comma => KeyCode::Comma,
130        VirtualKeyCode::Convert => KeyCode::Convert,
131        VirtualKeyCode::NumpadDecimal => KeyCode::NumpadDecimal,
132        VirtualKeyCode::NumpadDivide => KeyCode::NumpadDivide,
133        VirtualKeyCode::Equals => KeyCode::Equals,
134        VirtualKeyCode::Grave => KeyCode::Grave,
135        VirtualKeyCode::Kana => KeyCode::Kana,
136        VirtualKeyCode::Kanji => KeyCode::Kanji,
137        VirtualKeyCode::LAlt => KeyCode::LAlt,
138        VirtualKeyCode::LBracket => KeyCode::LBracket,
139        VirtualKeyCode::LControl => KeyCode::LControl,
140        VirtualKeyCode::LShift => KeyCode::LShift,
141        VirtualKeyCode::LWin => KeyCode::LWin,
142        VirtualKeyCode::Mail => KeyCode::Mail,
143        VirtualKeyCode::MediaSelect => KeyCode::MediaSelect,
144        VirtualKeyCode::MediaStop => KeyCode::MediaStop,
145        VirtualKeyCode::Minus => KeyCode::Minus,
146        VirtualKeyCode::NumpadMultiply => KeyCode::NumpadMultiply,
147        VirtualKeyCode::Mute => KeyCode::Mute,
148        VirtualKeyCode::MyComputer => KeyCode::MyComputer,
149        VirtualKeyCode::NavigateForward => KeyCode::NavigateForward,
150        VirtualKeyCode::NavigateBackward => KeyCode::NavigateBackward,
151        VirtualKeyCode::NextTrack => KeyCode::NextTrack,
152        VirtualKeyCode::NoConvert => KeyCode::NoConvert,
153        VirtualKeyCode::NumpadComma => KeyCode::NumpadComma,
154        VirtualKeyCode::NumpadEnter => KeyCode::NumpadEnter,
155        VirtualKeyCode::NumpadEquals => KeyCode::NumpadEquals,
156        VirtualKeyCode::OEM102 => KeyCode::OEM102,
157        VirtualKeyCode::Period => KeyCode::Period,
158        VirtualKeyCode::PlayPause => KeyCode::PlayPause,
159        VirtualKeyCode::Power => KeyCode::Power,
160        VirtualKeyCode::PrevTrack => KeyCode::PrevTrack,
161        VirtualKeyCode::RAlt => KeyCode::RAlt,
162        VirtualKeyCode::RBracket => KeyCode::RBracket,
163        VirtualKeyCode::RControl => KeyCode::RControl,
164        VirtualKeyCode::RShift => KeyCode::RShift,
165        VirtualKeyCode::RWin => KeyCode::RWin,
166        VirtualKeyCode::Semicolon => KeyCode::Semicolon,
167        VirtualKeyCode::Slash => KeyCode::Slash,
168        VirtualKeyCode::Sleep => KeyCode::Sleep,
169        VirtualKeyCode::Stop => KeyCode::Stop,
170        VirtualKeyCode::NumpadSubtract => KeyCode::NumpadSubtract,
171        VirtualKeyCode::Sysrq => KeyCode::Sysrq,
172        VirtualKeyCode::Tab => KeyCode::Tab,
173        VirtualKeyCode::Underline => KeyCode::Underline,
174        VirtualKeyCode::Unlabeled => KeyCode::Unlabeled,
175        VirtualKeyCode::VolumeDown => KeyCode::VolumeDown,
176        VirtualKeyCode::VolumeUp => KeyCode::VolumeUp,
177        VirtualKeyCode::Wake => KeyCode::Wake,
178        VirtualKeyCode::WebBack => KeyCode::WebBack,
179        VirtualKeyCode::WebFavorites => KeyCode::WebFavorites,
180        VirtualKeyCode::WebForward => KeyCode::WebForward,
181        VirtualKeyCode::WebHome => KeyCode::WebHome,
182        VirtualKeyCode::WebRefresh => KeyCode::WebRefresh,
183        VirtualKeyCode::WebSearch => KeyCode::WebSearch,
184        VirtualKeyCode::WebStop => KeyCode::WebStop,
185        VirtualKeyCode::Yen => KeyCode::Yen,
186        VirtualKeyCode::Copy => KeyCode::Copy,
187        VirtualKeyCode::Paste => KeyCode::Paste,
188        VirtualKeyCode::Cut => KeyCode::Cut,
189        VirtualKeyCode::Asterisk => KeyCode::Asterisk,
190        VirtualKeyCode::Plus => KeyCode::Plus,
191    }
192}
193
194/// Translates cursor icon from rg3d-ui library to glutin format.
195pub fn translate_cursor_icon(icon: crate::gui::message::CursorIcon) -> crate::window::CursorIcon {
196    match icon {
197        crate::gui::message::CursorIcon::Default => crate::window::CursorIcon::Default,
198        crate::gui::message::CursorIcon::Crosshair => crate::window::CursorIcon::Crosshair,
199        crate::gui::message::CursorIcon::Hand => crate::window::CursorIcon::Hand,
200        crate::gui::message::CursorIcon::Arrow => crate::window::CursorIcon::Arrow,
201        crate::gui::message::CursorIcon::Move => crate::window::CursorIcon::Move,
202        crate::gui::message::CursorIcon::Text => crate::window::CursorIcon::Text,
203        crate::gui::message::CursorIcon::Wait => crate::window::CursorIcon::Wait,
204        crate::gui::message::CursorIcon::Help => crate::window::CursorIcon::Help,
205        crate::gui::message::CursorIcon::Progress => crate::window::CursorIcon::Progress,
206        crate::gui::message::CursorIcon::NotAllowed => crate::window::CursorIcon::NotAllowed,
207        crate::gui::message::CursorIcon::ContextMenu => crate::window::CursorIcon::ContextMenu,
208        crate::gui::message::CursorIcon::Cell => crate::window::CursorIcon::Cell,
209        crate::gui::message::CursorIcon::VerticalText => crate::window::CursorIcon::VerticalText,
210        crate::gui::message::CursorIcon::Alias => crate::window::CursorIcon::Alias,
211        crate::gui::message::CursorIcon::Copy => crate::window::CursorIcon::Copy,
212        crate::gui::message::CursorIcon::NoDrop => crate::window::CursorIcon::NoDrop,
213        crate::gui::message::CursorIcon::Grab => crate::window::CursorIcon::Grab,
214        crate::gui::message::CursorIcon::Grabbing => crate::window::CursorIcon::Grabbing,
215        crate::gui::message::CursorIcon::AllScroll => crate::window::CursorIcon::AllScroll,
216        crate::gui::message::CursorIcon::ZoomIn => crate::window::CursorIcon::ZoomIn,
217        crate::gui::message::CursorIcon::ZoomOut => crate::window::CursorIcon::ZoomOut,
218        crate::gui::message::CursorIcon::EResize => crate::window::CursorIcon::EResize,
219        crate::gui::message::CursorIcon::NResize => crate::window::CursorIcon::NResize,
220        crate::gui::message::CursorIcon::NeResize => crate::window::CursorIcon::NeResize,
221        crate::gui::message::CursorIcon::NwResize => crate::window::CursorIcon::NwResize,
222        crate::gui::message::CursorIcon::SResize => crate::window::CursorIcon::SResize,
223        crate::gui::message::CursorIcon::SeResize => crate::window::CursorIcon::SeResize,
224        crate::gui::message::CursorIcon::SwResize => crate::window::CursorIcon::SwResize,
225        crate::gui::message::CursorIcon::WResize => crate::window::CursorIcon::WResize,
226        crate::gui::message::CursorIcon::EwResize => crate::window::CursorIcon::EwResize,
227        crate::gui::message::CursorIcon::NsResize => crate::window::CursorIcon::NsResize,
228        crate::gui::message::CursorIcon::NeswResize => crate::window::CursorIcon::NeswResize,
229        crate::gui::message::CursorIcon::NwseResize => crate::window::CursorIcon::NwseResize,
230        crate::gui::message::CursorIcon::ColResize => crate::window::CursorIcon::ColResize,
231        crate::gui::message::CursorIcon::RowResize => crate::window::CursorIcon::RowResize,
232    }
233}
234
235/// Translates window mouse button into rg3d-ui mouse button.
236pub fn translate_button(button: crate::event::MouseButton) -> crate::gui::message::MouseButton {
237    match button {
238        crate::event::MouseButton::Left => crate::gui::message::MouseButton::Left,
239        crate::event::MouseButton::Right => crate::gui::message::MouseButton::Right,
240        crate::event::MouseButton::Middle => crate::gui::message::MouseButton::Middle,
241        crate::event::MouseButton::Other(i) => crate::gui::message::MouseButton::Other(i),
242    }
243}
244
245/// Translates library button state into rg3d-ui button state.
246pub fn translate_state(state: ElementState) -> ButtonState {
247    match state {
248        ElementState::Pressed => ButtonState::Pressed,
249        ElementState::Released => ButtonState::Released,
250    }
251}
252
253/// Translates window event to rg3d-ui event.
254pub fn translate_event(event: &WindowEvent) -> Option<OsEvent> {
255    match event {
256        WindowEvent::ReceivedCharacter(c) => Some(OsEvent::Character(*c)),
257        WindowEvent::KeyboardInput { input, .. } => {
258            input.virtual_keycode.map(|key| OsEvent::KeyboardInput {
259                button: translate_key(key),
260                state: translate_state(input.state),
261            })
262        }
263        WindowEvent::CursorMoved { position, .. } => Some(OsEvent::CursorMoved {
264            position: Vector2::new(position.x as f32, position.y as f32),
265        }),
266        WindowEvent::MouseWheel { delta, .. } => match delta {
267            MouseScrollDelta::LineDelta(x, y) => Some(OsEvent::MouseWheel(*x, *y)),
268            MouseScrollDelta::PixelDelta(pos) => {
269                Some(OsEvent::MouseWheel(pos.x as f32, pos.y as f32))
270            }
271        },
272        WindowEvent::MouseInput { state, button, .. } => Some(OsEvent::MouseInput {
273            button: translate_button(*button),
274            state: translate_state(*state),
275        }),
276        &WindowEvent::ModifiersChanged(modifiers) => Some(OsEvent::KeyboardModifiers(
277            translate_keyboard_modifiers(modifiers),
278        )),
279        _ => None,
280    }
281}
282
283/// Translates keyboard modifiers to rg3d-ui keyboard modifiers.
284pub fn translate_keyboard_modifiers(modifiers: ModifiersState) -> KeyboardModifiers {
285    KeyboardModifiers {
286        alt: modifiers.alt(),
287        shift: modifiers.shift(),
288        control: modifiers.ctrl(),
289        system: modifiers.logo(),
290    }
291}
292
293/// Maps key code to its name. Can be useful if you making adjustable key bindings in your
294/// game and you need quickly map key code to its name.
295pub fn virtual_key_code_name(code: VirtualKeyCode) -> &'static str {
296    match code {
297        VirtualKeyCode::Key1 => "1",
298        VirtualKeyCode::Key2 => "2",
299        VirtualKeyCode::Key3 => "3",
300        VirtualKeyCode::Key4 => "4",
301        VirtualKeyCode::Key5 => "5",
302        VirtualKeyCode::Key6 => "6",
303        VirtualKeyCode::Key7 => "7",
304        VirtualKeyCode::Key8 => "8",
305        VirtualKeyCode::Key9 => "9",
306        VirtualKeyCode::Key0 => "0",
307        VirtualKeyCode::A => "A",
308        VirtualKeyCode::B => "B",
309        VirtualKeyCode::C => "C",
310        VirtualKeyCode::D => "D",
311        VirtualKeyCode::E => "E",
312        VirtualKeyCode::F => "F",
313        VirtualKeyCode::G => "G",
314        VirtualKeyCode::H => "H",
315        VirtualKeyCode::I => "I",
316        VirtualKeyCode::J => "J",
317        VirtualKeyCode::K => "K",
318        VirtualKeyCode::L => "L",
319        VirtualKeyCode::M => "M",
320        VirtualKeyCode::N => "N",
321        VirtualKeyCode::O => "O",
322        VirtualKeyCode::P => "P",
323        VirtualKeyCode::Q => "Q",
324        VirtualKeyCode::R => "R",
325        VirtualKeyCode::S => "S",
326        VirtualKeyCode::T => "T",
327        VirtualKeyCode::U => "U",
328        VirtualKeyCode::V => "V",
329        VirtualKeyCode::W => "W",
330        VirtualKeyCode::X => "X",
331        VirtualKeyCode::Y => "Y",
332        VirtualKeyCode::Z => "Z",
333        VirtualKeyCode::Escape => "Escape",
334        VirtualKeyCode::F1 => "F1",
335        VirtualKeyCode::F2 => "F2",
336        VirtualKeyCode::F3 => "F3",
337        VirtualKeyCode::F4 => "F4",
338        VirtualKeyCode::F5 => "F5",
339        VirtualKeyCode::F6 => "F6",
340        VirtualKeyCode::F7 => "F7",
341        VirtualKeyCode::F8 => "F8",
342        VirtualKeyCode::F9 => "F9",
343        VirtualKeyCode::F10 => "F10",
344        VirtualKeyCode::F11 => "F11",
345        VirtualKeyCode::F12 => "F12",
346        VirtualKeyCode::F13 => "F13",
347        VirtualKeyCode::F14 => "F14",
348        VirtualKeyCode::F15 => "F15",
349        VirtualKeyCode::F16 => "F16",
350        VirtualKeyCode::F17 => "F17",
351        VirtualKeyCode::F18 => "F18",
352        VirtualKeyCode::F19 => "F19",
353        VirtualKeyCode::F20 => "F20",
354        VirtualKeyCode::F21 => "F21",
355        VirtualKeyCode::F22 => "F22",
356        VirtualKeyCode::F23 => "F23",
357        VirtualKeyCode::F24 => "F24",
358        VirtualKeyCode::Snapshot => "Snapshot",
359        VirtualKeyCode::Scroll => "Scroll",
360        VirtualKeyCode::Pause => "Pause",
361        VirtualKeyCode::Insert => "Insert",
362        VirtualKeyCode::Home => "Home",
363        VirtualKeyCode::Delete => "Delete",
364        VirtualKeyCode::End => "End",
365        VirtualKeyCode::PageDown => "PageDown",
366        VirtualKeyCode::PageUp => "PageUp",
367        VirtualKeyCode::Left => "Left",
368        VirtualKeyCode::Up => "Up",
369        VirtualKeyCode::Right => "Right",
370        VirtualKeyCode::Down => "Down",
371        VirtualKeyCode::Back => "Back",
372        VirtualKeyCode::Return => "Return",
373        VirtualKeyCode::Space => "Space",
374        VirtualKeyCode::Compose => "Compose",
375        VirtualKeyCode::Caret => "Caret",
376        VirtualKeyCode::Numlock => "Numlock",
377        VirtualKeyCode::Numpad0 => "Numpad0",
378        VirtualKeyCode::Numpad1 => "Numpad1",
379        VirtualKeyCode::Numpad2 => "Numpad2",
380        VirtualKeyCode::Numpad3 => "Numpad3",
381        VirtualKeyCode::Numpad4 => "Numpad4",
382        VirtualKeyCode::Numpad5 => "Numpad5",
383        VirtualKeyCode::Numpad6 => "Numpad6",
384        VirtualKeyCode::Numpad7 => "Numpad7",
385        VirtualKeyCode::Numpad8 => "Numpad8",
386        VirtualKeyCode::Numpad9 => "Numpad9",
387        VirtualKeyCode::AbntC1 => "AbntC1",
388        VirtualKeyCode::AbntC2 => "AbntC2",
389        VirtualKeyCode::NumpadAdd => "NumpadAdd",
390        VirtualKeyCode::Apostrophe => "Apostrophe",
391        VirtualKeyCode::Apps => "Apps",
392        VirtualKeyCode::At => "At",
393        VirtualKeyCode::Ax => "Ax",
394        VirtualKeyCode::Backslash => "Backslash",
395        VirtualKeyCode::Calculator => "Calculator",
396        VirtualKeyCode::Capital => "Capital",
397        VirtualKeyCode::Colon => "Colon",
398        VirtualKeyCode::Comma => "Comma",
399        VirtualKeyCode::Convert => "Convert",
400        VirtualKeyCode::NumpadDecimal => "NumpadDecimal",
401        VirtualKeyCode::NumpadDivide => "NumpadDivide",
402        VirtualKeyCode::Equals => "Equals",
403        VirtualKeyCode::Grave => "Grave",
404        VirtualKeyCode::Kana => "Kana",
405        VirtualKeyCode::Kanji => "Kanji",
406        VirtualKeyCode::LAlt => "LAlt",
407        VirtualKeyCode::LBracket => "LBracket",
408        VirtualKeyCode::LControl => "LControl",
409        VirtualKeyCode::LShift => "LShift",
410        VirtualKeyCode::LWin => "LWin",
411        VirtualKeyCode::Mail => "Mail",
412        VirtualKeyCode::MediaSelect => "MediaSelect",
413        VirtualKeyCode::MediaStop => "MediaStop",
414        VirtualKeyCode::Minus => "Minus",
415        VirtualKeyCode::NumpadMultiply => "NumpadMultiply",
416        VirtualKeyCode::Mute => "Mute",
417        VirtualKeyCode::MyComputer => "MyComputer",
418        VirtualKeyCode::NavigateForward => "NavigateForward",
419        VirtualKeyCode::NavigateBackward => "NavigateBackward",
420        VirtualKeyCode::NextTrack => "NextTrack",
421        VirtualKeyCode::NoConvert => "NoConvert",
422        VirtualKeyCode::NumpadComma => "NumpadComma",
423        VirtualKeyCode::NumpadEnter => "NumpadEnter",
424        VirtualKeyCode::NumpadEquals => "NumpadEquals",
425        VirtualKeyCode::OEM102 => "OEM102",
426        VirtualKeyCode::Period => "Period",
427        VirtualKeyCode::PlayPause => "PlayPause",
428        VirtualKeyCode::Power => "Power",
429        VirtualKeyCode::PrevTrack => "PrevTrack",
430        VirtualKeyCode::RAlt => "RAlt",
431        VirtualKeyCode::RBracket => "RBracket",
432        VirtualKeyCode::RControl => "RControl",
433        VirtualKeyCode::RShift => "RShift",
434        VirtualKeyCode::RWin => "RWin",
435        VirtualKeyCode::Semicolon => "Semicolon",
436        VirtualKeyCode::Slash => "Slash",
437        VirtualKeyCode::Sleep => "Sleep",
438        VirtualKeyCode::Stop => "Stop",
439        VirtualKeyCode::NumpadSubtract => "NumpadSubtract",
440        VirtualKeyCode::Sysrq => "Sysrq",
441        VirtualKeyCode::Tab => "Tab",
442        VirtualKeyCode::Underline => "Underline",
443        VirtualKeyCode::Unlabeled => "Unlabeled",
444        VirtualKeyCode::VolumeDown => "VolumeDown",
445        VirtualKeyCode::VolumeUp => "VolumeUp",
446        VirtualKeyCode::Wake => "Wake",
447        VirtualKeyCode::WebBack => "WebBack",
448        VirtualKeyCode::WebFavorites => "WebFavorites",
449        VirtualKeyCode::WebForward => "WebForward",
450        VirtualKeyCode::WebHome => "WebHome",
451        VirtualKeyCode::WebRefresh => "WebRefresh",
452        VirtualKeyCode::WebSearch => "WebSearch",
453        VirtualKeyCode::WebStop => "WebStop",
454        VirtualKeyCode::Yen => "Yen",
455        VirtualKeyCode::Copy => "Copy",
456        VirtualKeyCode::Paste => "Paste",
457        VirtualKeyCode::Cut => "Cut",
458        VirtualKeyCode::Asterisk => "Asterisk",
459        VirtualKeyCode::Plus => "Plus",
460    }
461}
462
463/// Helper function to convert Option<Arc<T>> to Option<Arc<dyn Any>>.
464#[allow(clippy::manual_map)]
465pub fn into_any_arc<T: Any + Send + Sync>(
466    opt: Option<Arc<T>>,
467) -> Option<Arc<dyn Any + Send + Sync>> {
468    match opt {
469        Some(r) => Some(r),
470        None => None,
471    }
472}
473
474/// Converts engine's optional texture "pointer" to rg3d-ui's.
475pub fn into_gui_texture(this: Texture) -> draw::SharedTexture {
476    draw::SharedTexture(this.0.into_inner())
477}
478
479/// "Transmutes" array of any sized type to a slice of bytes.
480pub fn array_as_u8_slice<T: Sized>(v: &[T]) -> &'_ [u8] {
481    // SAFETY: It is safe to reinterpret data to read it.
482    unsafe {
483        std::slice::from_raw_parts(v.as_ptr() as *const u8, std::mem::size_of::<T>() * v.len())
484    }
485}
486
487/// "Transmutes" value of any sized type to a slice of bytes.
488pub fn value_as_u8_slice<T: Sized>(v: &T) -> &'_ [u8] {
489    // SAFETY: It is safe to reinterpret data to read it.
490    unsafe { std::slice::from_raw_parts(v as *const T as *const u8, std::mem::size_of::<T>()) }
491}
492
493/// Performs hashing of a sized value by interpreting it as raw memory.
494pub fn hash_as_bytes<T: Sized, H: Hasher>(value: &T, hasher: &mut H) {
495    hasher.write(value_as_u8_slice(value))
496}