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}