godot_core/builtin/
real.rs

1/*
2 * Copyright (c) godot-rust; Bromeon and contributors.
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
6 */
7
8/// Convenience conversion between `real` and `f32`/`f64`.
9///
10/// Clippy often complains if you do `f as f64` when `f` is already an `f64`. This trait exists to make it easy to
11/// convert between the different reals and floats without a lot of allowing clippy lints for your code.
12pub trait RealConv {
13    /// Cast this [`real`][type@real] to an [`f32`] using `as`.
14    // Clippy complains that this is an `as_*` function, but it takes a `self`. Since this uses `as` internally, it makes much more sense for
15    // it to be named `as_f32` rather than `to_f32`.
16    #[allow(clippy::wrong_self_convention)]
17    fn as_f32(self) -> f32;
18
19    /// Cast this [`real`][type@real] to an [`f64`] using `as`.
20    #[allow(clippy::wrong_self_convention)] // see above.
21    fn as_f64(self) -> f64;
22
23    /// Cast an [`f32`] to a [`real`][type@real] using `as`.
24    fn from_f32(f: f32) -> Self;
25
26    /// Cast an [`f64`] to a [`real`][type@real] using `as`.
27    fn from_f64(f: f64) -> Self;
28}
29
30#[cfg(not(feature = "double-precision"))] #[cfg_attr(published_docs, doc(cfg(not(feature = "double-precision"))))]
31mod real_mod {
32    /// Floating point type used for many structs and functions in Godot.
33    ///
34    /// This type is `f32` by default, and `f64` when the Cargo feature `double-precision` is enabled.
35    ///
36    /// This is not the `float` type in GDScript; that type is always 64-bits. Rather, many structs in Godot may use
37    /// either 32-bit or 64-bit floats, for example [`Vector2`][crate::builtin::Vector2]. To convert between [`real`] and [`f32`] or
38    /// [`f64`], see [`RealConv`](super::RealConv).
39    ///
40    /// See also the [Godot docs on float](https://docs.godotengine.org/en/stable/classes/class_float.html).
41    // As this is a scalar value, we will use a non-standard type name.
42    #[allow(non_camel_case_types)]
43    pub type real = f32;
44
45    impl super::RealConv for real {
46        #[inline]
47        fn as_f32(self) -> f32 {
48            self
49        }
50
51        #[inline]
52        fn as_f64(self) -> f64 {
53            self as f64
54        }
55
56        #[inline]
57        fn from_f32(f: f32) -> Self {
58            f
59        }
60
61        #[inline]
62        fn from_f64(f: f64) -> Self {
63            f as f32
64        }
65    }
66
67    /// Re-export of [`std::f32::consts`] or [`std::f64::consts`], depending on precision config.
68    pub mod real_consts {
69        pub use std::f32::consts::*;
70    }
71
72    /// A 2-dimensional vector from [`glam`]. Using a floating-point format compatible with [`real`].
73    pub type RVec2 = glam::Vec2;
74    /// A 3-dimensional vector from [`glam`]. Using a floating-point format compatible with [`real`].
75    pub type RVec3 = glam::Vec3;
76    /// A 4-dimensional vector from [`glam`]. Using a floating-point format compatible with [`real`].
77    pub type RVec4 = glam::Vec4;
78
79    /// A 2x2 column-major matrix from [`glam`]. Using a floating-point format compatible with [`real`].
80    pub type RMat2 = glam::Mat2;
81    /// A 3x3 column-major matrix from [`glam`]. Using a floating-point format compatible with [`real`].
82    pub type RMat3 = glam::Mat3;
83    /// A 4x4 column-major matrix from [`glam`]. Using a floating-point format compatible with [`real`].
84    pub type RMat4 = glam::Mat4;
85
86    /// A matrix from [`glam`] quaternion representing an orientation. Using a floating-point format compatible
87    /// with [`real`].
88    pub type RQuat = glam::Quat;
89
90    /// A 2D affine transform from [`glam`], which can represent translation, rotation, scaling and
91    /// shear. Using a floating-point format compatible with [`real`].
92    pub type RAffine2 = glam::Affine2;
93    /// A 3D affine transform from [`glam`], which can represent translation, rotation, scaling and
94    /// shear. Using a floating-point format compatible with [`real`].
95    pub type RAffine3 = glam::Affine3A;
96}
97
98#[cfg(feature = "double-precision")] #[cfg_attr(published_docs, doc(cfg(feature = "double-precision")))]
99mod real_mod {
100    /// Floating point type used for many structs and functions in Godot.
101    ///
102    /// This type is `f32` by default, and `f64` when the Cargo feature `double-precision` is enabled.
103    ///
104    /// This is not the `float` type in GDScript; that type is always 64-bits. Rather, many structs in Godot may use
105    /// either 32-bit or 64-bit floats, for example [`Vector2`](super::Vector2). To convert between [`real`] and [`f32`] or
106    /// [`f64`], see [`RealConv`](super::RealConv).
107    ///
108    /// See also the [Godot docs on float](https://docs.godotengine.org/en/stable/classes/class_float.html).
109    // As this is a scalar value, we will use a non-standard type name.
110    #[allow(non_camel_case_types)]
111    pub type real = f64;
112
113    impl super::RealConv for real {
114        #[inline]
115        fn as_f32(self) -> f32 {
116            self as f32
117        }
118
119        #[inline]
120        fn as_f64(self) -> f64 {
121            self
122        }
123
124        #[inline]
125        fn from_f32(f: f32) -> Self {
126            f as f64
127        }
128
129        #[inline]
130        fn from_f64(f: f64) -> Self {
131            f
132        }
133    }
134
135    /// Re-export of [`std::f32::consts`] or [`std::f64::consts`], depending on precision config.
136    pub mod real_consts {
137        pub use std::f64::consts::*;
138    }
139
140    /// A 2-dimensional vector from [`glam`]. Using a floating-point format compatible with [`real`].
141    pub type RVec2 = glam::DVec2;
142    /// A 3-dimensional vector from [`glam`]. Using a floating-point format compatible with [`real`].
143    pub type RVec3 = glam::DVec3;
144    /// A 4-dimensional vector from [`glam`]. Using a floating-point format compatible with [`real`].
145    pub type RVec4 = glam::DVec4;
146
147    /// A 2x2 column-major matrix from [`glam`]. Using a floating-point format compatible with [`real`].
148    pub type RMat2 = glam::DMat2;
149    /// A 3x3 column-major matrix from [`glam`]. Using a floating-point format compatible with [`real`].
150    pub type RMat3 = glam::DMat3;
151    /// A 4x4 column-major matrix from [`glam`]. Using a floating-point format compatible with [`real`].
152    pub type RMat4 = glam::DMat4;
153
154    /// A matrix from [`glam`] quaternion representing an orientation. Using a floating-point format
155    /// compatible with [`real`].
156    pub type RQuat = glam::DQuat;
157
158    /// A 2D affine transform from [`glam`], which can represent translation, rotation, scaling and
159    /// shear. Using a floating-point format compatible with [`real`].
160    pub type RAffine2 = glam::DAffine2;
161    /// A 3D affine transform from [`glam`], which can represent translation, rotation, scaling and
162    /// shear. Using a floating-point format compatible with [`real`].
163    pub type RAffine3 = glam::DAffine3;
164}
165
166// Public symbols (note that macro `real!` is re-exported in `lib.rs`)
167#[rustfmt::skip] // Do not reorder.
168pub use real_mod::{real, real_consts};
169
170// ----------------------------------------------------------------------------------------------------------------------------------------------
171
172// Internal re-exports
173pub(crate) use real_mod::*;
174
175/// A macro to coerce float-literals into the [`real`] type.
176///
177/// Mainly used where you'd normally use a suffix to specify the type, such as `115.0f32`.
178///
179/// # Examples
180///
181/// Rust is not able to infer the `self` type of this call to `to_radians`:
182/// ```compile_fail
183/// use godot::builtin::real;
184///
185/// let radians: real = 115.0.to_radians();
186/// ```
187/// But we cannot add a suffix to the literal, since it may be either `f32` or
188/// `f64` depending on the context. So instead we use our macro:
189/// ```
190/// use godot::builtin::real;
191///
192/// let radians: real = real!(115.0).to_radians();
193/// ```
194#[macro_export]
195macro_rules! real {
196    ($f:literal) => {{
197        let f: $crate::builtin::real = $f;
198        f
199    }};
200}
201
202/// Array of [`real`]s.
203///
204/// The expression has type `[real; N]` where `N` is the number of elements in the array.
205///
206/// # Example
207/// ```
208/// use godot_core::builtin::{real, reals};
209///
210/// let arr = reals![1.0, 2.0, 3.0];
211/// assert_eq!(arr[1], real!(2.0));
212/// ```
213#[macro_export]
214macro_rules! reals {
215    ($($f:literal),* $(,)?) => {{
216        let arr = [$($crate::real!($f)),*];
217        arr
218    }};
219}