|
4 | 4 | * file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
5 | 5 | */
|
6 | 6 |
|
| 7 | +use std::fmt; |
| 8 | + |
7 | 9 | use godot_ffi as sys;
|
8 | 10 | use sys::{ffi_methods, GodotFfi};
|
9 | 11 |
|
10 |
| -type Inner = glam::f32::Vec2; |
11 |
| -//type Inner = glam::f64::DVec2; |
| 12 | +use crate::builtin::Vector2i; |
12 | 13 |
|
13 |
| -#[derive(Default, Copy, Clone, Debug, PartialEq)] |
| 14 | +/// Vector used for 2D math using floating point coordinates. |
| 15 | +/// |
| 16 | +/// 2-element structure that can be used to represent positions in 2D space or any other pair of |
| 17 | +/// numeric values. |
| 18 | +/// |
| 19 | +/// It uses floating-point coordinates of 32-bit precision, unlike the engine's `float` type which |
| 20 | +/// is always 64-bit. The engine can be compiled with the option `precision=double` to use 64-bit |
| 21 | +/// vectors, but this is not yet supported in the `gdextension` crate. |
| 22 | +/// |
| 23 | +/// See [`Vector2i`] for its integer counterpart. |
| 24 | +#[derive(Debug, Default, Clone, Copy, PartialEq)] |
14 | 25 | #[repr(C)]
|
15 | 26 | pub struct Vector2 {
|
16 |
| - inner: Inner, |
| 27 | + /// The vector's X component. |
| 28 | + pub x: f32, |
| 29 | + /// The vector's Y component. |
| 30 | + pub y: f32, |
17 | 31 | }
|
18 | 32 |
|
19 | 33 | impl Vector2 {
|
20 |
| - pub fn new(x: f32, y: f32) -> Self { |
21 |
| - Self { |
22 |
| - inner: Inner::new(x, y), |
23 |
| - } |
| 34 | + /// Vector with all components set to `0.0`. |
| 35 | + pub const ZERO: Self = Self::splat(0.0); |
| 36 | + |
| 37 | + /// Vector with all components set to `1.0`. |
| 38 | + pub const ONE: Self = Self::splat(1.0); |
| 39 | + |
| 40 | + /// Vector with all components set to `f32::INFINITY`. |
| 41 | + pub const INF: Self = Self::splat(f32::INFINITY); |
| 42 | + |
| 43 | + /// Unit vector in -X direction (right in 2D coordinate system). |
| 44 | + pub const LEFT: Self = Self::new(-1.0, 0.0); |
| 45 | + |
| 46 | + /// Unit vector in +X direction (right in 2D coordinate system). |
| 47 | + pub const RIGHT: Self = Self::new(1.0, 0.0); |
| 48 | + |
| 49 | + /// Unit vector in -Y direction (up in 2D coordinate system). |
| 50 | + pub const UP: Self = Self::new(0.0, -1.0); |
| 51 | + |
| 52 | + /// Unit vector in +Y direction (down in 2D coordinate system). |
| 53 | + pub const DOWN: Self = Self::new(0.0, 1.0); |
| 54 | + |
| 55 | + /// Constructs a new `Vector2` from the given `x` and `y`. |
| 56 | + pub const fn new(x: f32, y: f32) -> Self { |
| 57 | + Self { x, y } |
24 | 58 | }
|
25 | 59 |
|
26 |
| - pub fn from_inner(inner: Inner) -> Self { |
27 |
| - Self { inner } |
| 60 | + /// Constructs a new `Vector2` with both components set to `v`. |
| 61 | + pub const fn splat(v: f32) -> Self { |
| 62 | + Self::new(v, v) |
28 | 63 | }
|
29 | 64 |
|
30 |
| - /// only for testing |
31 |
| - pub fn inner(self) -> Inner { |
32 |
| - self.inner |
| 65 | + /// Constructs a new `Vector2` from a [`Vector2i`]. |
| 66 | + pub const fn from_vector2i(v: Vector2i) -> Self { |
| 67 | + Self { |
| 68 | + x: v.x as f32, |
| 69 | + y: v.y as f32, |
| 70 | + } |
33 | 71 | }
|
34 | 72 |
|
35 |
| - // Hacks for example |
36 |
| - // pub fn length(self) -> f32 { |
37 |
| - // self.inner.length() |
38 |
| - // } |
39 |
| - // pub fn normalized(self) -> Vector2 { |
40 |
| - // Self::from_inner(self.inner.normalize()) |
41 |
| - // } |
| 73 | + /// Returns the result of rotating this vector by `angle` (in radians). |
42 | 74 | pub fn rotated(self, angle: f32) -> Self {
|
43 |
| - Self::from_inner(glam::Affine2::from_angle(angle).transform_vector2(self.inner)) |
| 75 | + Self::from_glam(glam::Affine2::from_angle(angle).transform_vector2(self.to_glam())) |
44 | 76 | }
|
45 |
| -} |
46 | 77 |
|
47 |
| -impl GodotFfi for Vector2 { |
48 |
| - ffi_methods! { type sys::GDExtensionTypePtr = *mut Self; .. } |
49 |
| -} |
| 78 | + /// Converts the corresponding `glam` type to `Self`. |
| 79 | + fn from_glam(v: glam::Vec2) -> Self { |
| 80 | + Self::new(v.x, v.y) |
| 81 | + } |
50 | 82 |
|
51 |
| -impl std::fmt::Display for Vector2 { |
52 |
| - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
53 |
| - self.inner.fmt(f) |
| 83 | + /// Converts `self` to the corresponding `glam` type. |
| 84 | + fn to_glam(self) -> glam::Vec2 { |
| 85 | + glam::Vec2::new(self.x, self.y) |
54 | 86 | }
|
55 | 87 | }
|
56 | 88 |
|
57 |
| -// ---------------------------------------------------------------------------------------------------------------------------------------------- |
| 89 | +/// Formats the vector like Godot: `(x, y)`. |
| 90 | +impl fmt::Display for Vector2 { |
| 91 | + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 92 | + write!(f, "({}, {})", self.x, self.y) |
| 93 | + } |
| 94 | +} |
58 | 95 |
|
59 |
| -type IInner = glam::IVec2; |
| 96 | +impl_common_vector_fns!(Vector2, f32); |
| 97 | +impl_float_vector_fns!(Vector2, f32); |
| 98 | +impl_vector_operators!(Vector2, f32, (x, y)); |
| 99 | +impl_vector_index!(Vector2, f32, (x, y), Vector2Axis, (X, Y)); |
60 | 100 |
|
61 |
| -#[derive(Default, Copy, Clone, Debug, Eq, PartialEq)] |
62 |
| -#[repr(C)] |
63 |
| -pub struct Vector2i { |
64 |
| - inner: IInner, |
| 101 | +impl GodotFfi for Vector2 { |
| 102 | + ffi_methods! { type sys::GDExtensionTypePtr = *mut Self; .. } |
65 | 103 | }
|
66 | 104 |
|
67 |
| -impl Vector2i { |
68 |
| - pub fn new(x: i32, y: i32) -> Self { |
69 |
| - Self { |
70 |
| - inner: IInner::new(x, y), |
71 |
| - } |
72 |
| - } |
| 105 | +/// Enumerates the axes in a [`Vector2`]. |
| 106 | +#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] |
| 107 | +#[repr(i32)] |
| 108 | +pub enum Vector2Axis { |
| 109 | + /// The X axis. |
| 110 | + X, |
| 111 | + /// The Y axis. |
| 112 | + Y, |
73 | 113 | }
|
74 | 114 |
|
75 |
| -impl GodotFfi for Vector2i { |
| 115 | +impl GodotFfi for Vector2Axis { |
76 | 116 | ffi_methods! { type sys::GDExtensionTypePtr = *mut Self; .. }
|
77 | 117 | }
|
78 |
| - |
79 |
| -impl std::fmt::Display for Vector2i { |
80 |
| - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
81 |
| - self.inner.fmt(f) |
82 |
| - } |
83 |
| -} |
|
0 commit comments