Skip to content

Fix floating point math #15239

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
c219f67
add disallowed-methods
BenjaminBrienen Sep 15, 2024
a2c4901
use bevy::math for floating point ops
BenjaminBrienen Sep 15, 2024
9e9ee01
Merge branch 'main' into fix-floating-point-math
BenjaminBrienen Sep 15, 2024
a5a176c
fmt
BenjaminBrienen Sep 15, 2024
7ff7087
missed one
BenjaminBrienen Sep 15, 2024
faffec6
fmt
BenjaminBrienen Sep 15, 2024
bdbe8a1
missed a couple more
BenjaminBrienen Sep 15, 2024
0d31548
fmt
BenjaminBrienen Sep 15, 2024
94de372
missing use
BenjaminBrienen Sep 15, 2024
21a260a
fix doc and fmt
BenjaminBrienen Sep 15, 2024
8345218
fix more
BenjaminBrienen Sep 15, 2024
c10b378
add use
BenjaminBrienen Sep 15, 2024
448c691
fmt
BenjaminBrienen Sep 16, 2024
388f7ec
anisotropy
BenjaminBrienen Sep 16, 2024
c624896
more
BenjaminBrienen Sep 16, 2024
12a2467
fix
BenjaminBrienen Sep 16, 2024
c107ecd
many_lights
BenjaminBrienen Sep 16, 2024
0174518
feedback from PR review
BenjaminBrienen Sep 16, 2024
6fd9ffa
more feedback from pr
BenjaminBrienen Sep 16, 2024
6ac57a8
more feedback
BenjaminBrienen Sep 16, 2024
b8d1cb9
remove use
BenjaminBrienen Sep 16, 2024
0e4cb26
undo change
BenjaminBrienen Sep 16, 2024
154fb9c
lib default
BenjaminBrienen Sep 16, 2024
6464451
Revert default libm feature
alice-i-cecile Sep 16, 2024
06ffd42
Update crates/bevy_gizmos/src/arcs.rs
BenjaminBrienen Sep 16, 2024
c8e309e
Update crates/bevy_render/src/mesh/primitives/dim3/capsule.rs
BenjaminBrienen Sep 16, 2024
2583494
Update crates/bevy_render/src/mesh/primitives/dim3/capsule.rs
BenjaminBrienen Sep 16, 2024
8d4b77b
Update crates/bevy_color/src/lcha.rs
BenjaminBrienen Sep 16, 2024
8abaf9f
Update crates/bevy_color/src/oklcha.rs
BenjaminBrienen Sep 16, 2024
9f25494
Update crates/bevy_pbr/src/pbr_material.rs
BenjaminBrienen Sep 16, 2024
b1e93bc
feedback from PR
BenjaminBrienen Sep 16, 2024
1224f68
Merge branch 'fix-floating-point-math' of https://github.com/Benjamin…
BenjaminBrienen Sep 16, 2024
6e29c7e
fmt
BenjaminBrienen Sep 16, 2024
4ab5679
add ops to prelude and use it explicitly
BenjaminBrienen Sep 16, 2024
33e5ed5
fmt
BenjaminBrienen Sep 16, 2024
9397361
fix unresolved import
BenjaminBrienen Sep 16, 2024
1b2888f
use
BenjaminBrienen Sep 16, 2024
1cd83d8
fmt again ???
BenjaminBrienen Sep 16, 2024
ac4e530
fix
BenjaminBrienen Sep 16, 2024
61efa14
cleanup
BenjaminBrienen Sep 16, 2024
bdb9471
fmt
BenjaminBrienen Sep 16, 2024
ed55369
fix example
BenjaminBrienen Sep 16, 2024
8a55050
fix more examples
BenjaminBrienen Sep 16, 2024
951bce8
fmt
BenjaminBrienen Sep 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions clippy.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,33 @@ doc-valid-idents = [
"WebGPU",
"..",
]

disallowed-methods = [
{ path = "f32::powi", reason = "use bevy_math::ops::FloatPow::squared, bevy_math::ops::FloatPow::cubed, or bevy_math::ops::powf instead for libm determinism" },
{ path = "f32::log", reason = "use bevy_math::ops::ln, bevy_math::ops::log2, or bevy_math::ops::log10 instead for libm determinism" },
{ path = "f32::abs_sub", reason = "deprecated and deeply confusing method" },
{ path = "f32::powf", reason = "use bevy_math::ops::powf instead for libm determinism" },
{ path = "f32::exp", reason = "use bevy_math::ops::exp instead for libm determinism" },
{ path = "f32::exp2", reason = "use bevy_math::ops::exp2 instead for libm determinism" },
{ path = "f32::ln", reason = "use bevy_math::ops::ln instead for libm determinism" },
{ path = "f32::log2", reason = "use bevy_math::ops::log2 instead for libm determinism" },
{ path = "f32::log10", reason = "use bevy_math::ops::log10 instead for libm determinism" },
{ path = "f32::cbrt", reason = "use bevy_math::ops::cbrt instead for libm determinism" },
{ path = "f32::hypot", reason = "use bevy_math::ops::hypot instead for libm determinism" },
{ path = "f32::sin", reason = "use bevy_math::ops::sin instead for libm determinism" },
{ path = "f32::cos", reason = "use bevy_math::ops::cos instead for libm determinism" },
{ path = "f32::tan", reason = "use bevy_math::ops::tan instead for libm determinism" },
{ path = "f32::asin", reason = "use bevy_math::ops::asin instead for libm determinism" },
{ path = "f32::acos", reason = "use bevy_math::ops::acos instead for libm determinism" },
{ path = "f32::atan", reason = "use bevy_math::ops::atan instead for libm determinism" },
{ path = "f32::atan2", reason = "use bevy_math::ops::atan2 instead for libm determinism" },
{ path = "f32::sin_cos", reason = "use bevy_math::ops::sin_cos instead for libm determinism" },
{ path = "f32::exp_m1", reason = "use bevy_math::ops::exp_m1 instead for libm determinism" },
{ path = "f32::ln_1p", reason = "use bevy_math::ops::ln_1p instead for libm determinism" },
{ path = "f32::sinh", reason = "use bevy_math::ops::sinh instead for libm determinism" },
{ path = "f32::cosh", reason = "use bevy_math::ops::cosh instead for libm determinism" },
{ path = "f32::tanh", reason = "use bevy_math::ops::tanh instead for libm determinism" },
{ path = "f32::asinh", reason = "use bevy_math::ops::asinh instead for libm determinism" },
{ path = "f32::acosh", reason = "use bevy_math::ops::acosh instead for libm determinism" },
{ path = "f32::atanh", reason = "use bevy_math::ops::atanh instead for libm determinism" },
]
10 changes: 5 additions & 5 deletions crates/bevy_animation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use bevy_app::{App, Plugin, PostUpdate};
use bevy_asset::{Asset, AssetApp, Assets, Handle};
use bevy_core::Name;
use bevy_ecs::{entity::MapEntities, prelude::*, reflect::ReflectMapEntities};
use bevy_math::{FloatExt, Quat, Vec3};
use bevy_math::{FloatExt, FloatPow, Quat, Vec3};
use bevy_reflect::std_traits::ReflectDefault;
use bevy_reflect::Reflect;
use bevy_render::mesh::morph::MorphWeights;
Expand Down Expand Up @@ -1211,10 +1211,10 @@ fn cubic_spline_interpolation<T>(
where
T: Mul<f32, Output = T> + Add<Output = T>,
{
value_start * (2.0 * lerp.powi(3) - 3.0 * lerp.powi(2) + 1.0)
+ tangent_out_start * (step_duration) * (lerp.powi(3) - 2.0 * lerp.powi(2) + lerp)
+ value_end * (-2.0 * lerp.powi(3) + 3.0 * lerp.powi(2))
+ tangent_in_end * step_duration * (lerp.powi(3) - lerp.powi(2))
value_start * (2.0 * lerp.cubed() - 3.0 * lerp.squared() + 1.0)
+ tangent_out_start * (step_duration) * (lerp.cubed() - 2.0 * lerp.squared() + lerp)
+ value_end * (-2.0 * lerp.cubed() + 3.0 * lerp.squared())
+ tangent_in_end * step_duration * (lerp.cubed() - lerp.squared())
}

/// Adds animation support to an app
Expand Down
14 changes: 7 additions & 7 deletions crates/bevy_color/src/laba.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::{
impl_componentwise_vector_space, Alpha, ColorToComponents, Gray, Hsla, Hsva, Hwba, LinearRgba,
Luminance, Mix, Oklaba, Srgba, StandardColor, Xyza,
};
use bevy_math::{Vec3, Vec4};
use bevy_math::{ops, Vec3, Vec4};
#[cfg(feature = "bevy_reflect")]
use bevy_reflect::prelude::*;

Expand Down Expand Up @@ -225,7 +225,7 @@ impl From<Laba> for Xyza {
let fx = a / 500.0 + fy;
let fz = fy - b / 200.0;
let xr = {
let fx3 = fx.powf(3.0);
let fx3 = ops::powf(fx, 3.0);

if fx3 > Laba::CIE_EPSILON {
fx3
Expand All @@ -234,12 +234,12 @@ impl From<Laba> for Xyza {
}
};
let yr = if l > Laba::CIE_EPSILON * Laba::CIE_KAPPA {
((l + 16.0) / 116.0).powf(3.0)
ops::powf((l + 16.0) / 116.0, 3.0)
} else {
l / Laba::CIE_KAPPA
};
let zr = {
let fz3 = fz.powf(3.0);
let fz3 = ops::powf(fz, 3.0);

if fz3 > Laba::CIE_EPSILON {
fz3
Expand All @@ -262,17 +262,17 @@ impl From<Xyza> for Laba {
let yr = y / Xyza::D65_WHITE.y;
let zr = z / Xyza::D65_WHITE.z;
let fx = if xr > Laba::CIE_EPSILON {
xr.cbrt()
ops::cbrt(xr)
} else {
(Laba::CIE_KAPPA * xr + 16.0) / 116.0
};
let fy = if yr > Laba::CIE_EPSILON {
yr.cbrt()
ops::cbrt(yr)
} else {
(Laba::CIE_KAPPA * yr + 16.0) / 116.0
};
let fz = if yr > Laba::CIE_EPSILON {
zr.cbrt()
ops::cbrt(zr)
} else {
(Laba::CIE_KAPPA * zr + 16.0) / 116.0
};
Expand Down
11 changes: 6 additions & 5 deletions crates/bevy_color/src/lcha.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::{
Alpha, ColorToComponents, Gray, Hue, Laba, LinearRgba, Luminance, Mix, Srgba, StandardColor,
Xyza,
};
use bevy_math::{Vec3, Vec4};
use bevy_math::{ops, Vec3, Vec4};
#[cfg(feature = "bevy_reflect")]
use bevy_reflect::prelude::*;

Expand Down Expand Up @@ -257,8 +257,9 @@ impl From<Lcha> for Laba {
) -> Self {
// Based on http://www.brucelindbloom.com/index.html?Eqn_LCH_to_Lab.html
let l = lightness;
let a = chroma * hue.to_radians().cos();
let b = chroma * hue.to_radians().sin();
let (sin, cos) = ops::sin_cos(hue.to_radians());
let a = chroma * cos;
let b = chroma * sin;

Laba::new(l, a, b, alpha)
}
Expand All @@ -274,9 +275,9 @@ impl From<Laba> for Lcha {
}: Laba,
) -> Self {
// Based on http://www.brucelindbloom.com/index.html?Eqn_Lab_to_LCH.html
let c = (a.powf(2.0) + b.powf(2.0)).sqrt();
let c = ops::hypot(a, b);
let h = {
let h = b.to_radians().atan2(a.to_radians()).to_degrees();
let h = ops::atan2(b.to_radians(), a.to_radians()).to_degrees();

if h < 0.0 {
h + 360.0
Expand Down
14 changes: 7 additions & 7 deletions crates/bevy_color/src/oklaba.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::{
color_difference::EuclideanDistance, impl_componentwise_vector_space, Alpha, ColorToComponents,
Gray, Hsla, Hsva, Hwba, Lcha, LinearRgba, Luminance, Mix, Srgba, StandardColor, Xyza,
};
use bevy_math::{Vec3, Vec4};
use bevy_math::{ops, FloatPow, Vec3, Vec4};
#[cfg(feature = "bevy_reflect")]
use bevy_reflect::prelude::*;

Expand Down Expand Up @@ -156,9 +156,9 @@ impl Luminance for Oklaba {
impl EuclideanDistance for Oklaba {
#[inline]
fn distance_squared(&self, other: &Self) -> f32 {
(self.lightness - other.lightness).powi(2)
+ (self.a - other.a).powi(2)
+ (self.b - other.b).powi(2)
(self.lightness - other.lightness).squared()
+ (self.a - other.a).squared()
+ (self.b - other.b).squared()
}
}

Expand Down Expand Up @@ -229,9 +229,9 @@ impl From<LinearRgba> for Oklaba {
let l = 0.4122214708 * red + 0.5363325363 * green + 0.0514459929 * blue;
let m = 0.2119034982 * red + 0.6806995451 * green + 0.1073969566 * blue;
let s = 0.0883024619 * red + 0.2817188376 * green + 0.6299787005 * blue;
let l_ = l.cbrt();
let m_ = m.cbrt();
let s_ = s.cbrt();
let l_ = ops::cbrt(l);
let m_ = ops::cbrt(m);
let s_ = ops::cbrt(s);
let l = 0.2104542553 * l_ + 0.7936177850 * m_ - 0.0040720468 * s_;
let a = 1.9779984951 * l_ - 2.4285922050 * m_ + 0.4505937099 * s_;
let b = 0.0259040371 * l_ + 0.7827717662 * m_ - 0.8086757660 * s_;
Expand Down
17 changes: 9 additions & 8 deletions crates/bevy_color/src/oklcha.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::{
color_difference::EuclideanDistance, Alpha, ColorToComponents, Gray, Hsla, Hsva, Hue, Hwba,
Laba, Lcha, LinearRgba, Luminance, Mix, Oklaba, Srgba, StandardColor, Xyza,
};
use bevy_math::{Vec3, Vec4};
use bevy_math::{ops, FloatPow, Vec3, Vec4};
#[cfg(feature = "bevy_reflect")]
use bevy_reflect::prelude::*;

Expand Down Expand Up @@ -191,9 +191,9 @@ impl Luminance for Oklcha {
impl EuclideanDistance for Oklcha {
#[inline]
fn distance_squared(&self, other: &Self) -> f32 {
(self.lightness - other.lightness).powi(2)
+ (self.chroma - other.chroma).powi(2)
+ (self.hue - other.hue).powi(2)
(self.lightness - other.lightness).squared()
+ (self.chroma - other.chroma).squared()
+ (self.hue - other.hue).squared()
}
}

Expand Down Expand Up @@ -260,8 +260,8 @@ impl From<Oklaba> for Oklcha {
alpha,
}: Oklaba,
) -> Self {
let chroma = a.hypot(b);
let hue = b.atan2(a).to_degrees();
let chroma = ops::hypot(a, b);
let hue = ops::atan2(b, a).to_degrees();

let hue = if hue < 0.0 { hue + 360.0 } else { hue };

Expand All @@ -279,8 +279,9 @@ impl From<Oklcha> for Oklaba {
}: Oklcha,
) -> Self {
let l = lightness;
let a = chroma * hue.to_radians().cos();
let b = chroma * hue.to_radians().sin();
let (sin, cos) = ops::sin_cos(hue.to_radians());
let a = chroma * cos;
let b = chroma * sin;

Oklaba::new(l, a, b, alpha)
}
Expand Down
6 changes: 3 additions & 3 deletions crates/bevy_color/src/srgba.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
impl_componentwise_vector_space, Alpha, ColorToComponents, ColorToPacked, Gray, LinearRgba,
Luminance, Mix, StandardColor, Xyza,
};
use bevy_math::{Vec3, Vec4};
use bevy_math::{ops, Vec3, Vec4};
#[cfg(feature = "bevy_reflect")]
use bevy_reflect::prelude::*;
use thiserror::Error;
Expand Down Expand Up @@ -215,7 +215,7 @@ impl Srgba {
if value <= 0.04045 {
value / 12.92 // linear falloff in dark values
} else {
((value + 0.055) / 1.055).powf(2.4) // gamma curve in other area
ops::powf((value + 0.055) / 1.055, 2.4) // gamma curve in other area
}
}

Expand All @@ -228,7 +228,7 @@ impl Srgba {
if value <= 0.0031308 {
value * 12.92 // linear falloff in dark values
} else {
(1.055 * value.powf(1.0 / 2.4)) - 0.055 // gamma curve in other area
(1.055 * ops::powf(value, 1.0 / 2.4)) - 0.055 // gamma curve in other area
}
}
}
Expand Down
10 changes: 6 additions & 4 deletions crates/bevy_core_pipeline/src/bloom/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::{
use bevy_app::{App, Plugin};
use bevy_asset::{load_internal_asset, Handle};
use bevy_ecs::{prelude::*, query::QueryItem};
use bevy_math::UVec2;
use bevy_math::{ops, UVec2};
use bevy_render::{
camera::ExtractedCamera,
diagnostic::RecordDiagnostics,
Expand Down Expand Up @@ -462,9 +462,11 @@ fn prepare_bloom_bind_groups(
/// This function can be visually previewed for all values of *mip* (normalized) with tweakable
/// [`Bloom`] parameters on [Desmos graphing calculator](https://www.desmos.com/calculator/ncc8xbhzzl).
fn compute_blend_factor(bloom: &Bloom, mip: f32, max_mip: f32) -> f32 {
let mut lf_boost = (1.0
- (1.0 - (mip / max_mip)).powf(1.0 / (1.0 - bloom.low_frequency_boost_curvature)))
* bloom.low_frequency_boost;
let mut lf_boost =
(1.0 - ops::powf(
1.0 - (mip / max_mip),
1.0 / (1.0 - bloom.low_frequency_boost_curvature),
)) * bloom.low_frequency_boost;
let high_pass_lq = 1.0
- (((mip / max_mip) - bloom.high_pass_frequency) / bloom.high_pass_frequency)
.clamp(0.0, 1.0);
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_core_pipeline/src/dof/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use bevy_ecs::{
system::{lifetimeless::Read, Commands, Query, Res, ResMut, Resource},
world::{FromWorld, World},
};
use bevy_math::ops;
use bevy_reflect::{prelude::ReflectDefault, Reflect};
use bevy_render::{
camera::{PhysicalCameraParameters, Projection},
Expand Down Expand Up @@ -848,7 +849,7 @@ fn extract_depth_of_field_settings(
///
/// See <https://photo.stackexchange.com/a/97218>.
pub fn calculate_focal_length(sensor_height: f32, fov: f32) -> f32 {
0.5 * sensor_height / f32::tan(0.5 * fov)
0.5 * sensor_height / ops::tan(0.5 * fov)
}

impl DepthOfFieldPipelines {
Expand Down
14 changes: 7 additions & 7 deletions crates/bevy_ecs/src/query/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIter<'w, 's, D, F> {

let range = range.unwrap_or(0..table.entity_count());
accum =
// SAFETY:
// SAFETY:
// - The fetched table matches both D and F
// - caller ensures `range` is within `[0, table.entity_count)`
// - The if block ensures that the query iteration is dense
Expand Down Expand Up @@ -2083,15 +2083,15 @@ mod tests {
let mut query = world.query::<&Sparse>();
let mut iter = query.iter(&world);
println!(
"before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
"before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
iter.cursor.archetype_entities.len(),
iter.cursor.table_entities.len(),
iter.cursor.current_len,
iter.cursor.current_row
);
_ = iter.next();
println!(
"after_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
"after_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
iter.cursor.archetype_entities.len(),
iter.cursor.table_entities.len(),
iter.cursor.current_len,
Expand All @@ -2108,15 +2108,15 @@ mod tests {
let mut query = world.query::<(&A, &Sparse)>();
let mut iter = query.iter(&world);
println!(
"before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
"before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
iter.cursor.archetype_entities.len(),
iter.cursor.table_entities.len(),
iter.cursor.current_len,
iter.cursor.current_row
);
_ = iter.next();
println!(
"after_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
"after_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
iter.cursor.archetype_entities.len(),
iter.cursor.table_entities.len(),
iter.cursor.current_len,
Expand All @@ -2136,7 +2136,7 @@ mod tests {
let mut query = world.query::<(&A, &Sparse)>();
let mut iter = query.iter(&world);
println!(
"before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
"before_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
iter.cursor.archetype_entities.len(),
iter.cursor.table_entities.len(),
iter.cursor.current_len,
Expand All @@ -2145,7 +2145,7 @@ mod tests {
assert!(iter.cursor.table_entities.len() | iter.cursor.archetype_entities.len() == 0);
_ = iter.next();
println!(
"after_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
"after_next_call: archetype_entities: {} table_entities: {} current_len: {} current_row: {}",
iter.cursor.archetype_entities.len(),
iter.cursor.table_entities.len(),
iter.cursor.current_len,
Expand Down
3 changes: 1 addition & 2 deletions crates/bevy_gizmos/src/arcs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,7 @@ fn arc_2d_inner(arc_angle: f32, radius: f32, resolution: u32) -> impl Iterator<I
(0..=resolution)
.map(move |n| arc_angle * n as f32 / resolution as f32)
.map(|angle| angle + FRAC_PI_2)
.map(f32::sin_cos)
.map(|(sin, cos)| Vec2::new(cos, sin))
.map(Vec2::from_angle)
.map(move |vec2| vec2 * radius)
}

Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_gizmos/src/circles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

use crate::prelude::{GizmoConfigGroup, Gizmos};
use bevy_color::Color;
use bevy_math::{Isometry2d, Isometry3d};
use bevy_math::{ops, Isometry2d, Isometry3d};
use bevy_math::{Quat, Vec2, Vec3};
use std::f32::consts::TAU;

Expand All @@ -14,7 +14,7 @@ pub(crate) const DEFAULT_CIRCLE_RESOLUTION: u32 = 32;
fn ellipse_inner(half_size: Vec2, resolution: u32) -> impl Iterator<Item = Vec2> {
(0..resolution + 1).map(move |i| {
let angle = i as f32 * TAU / resolution as f32;
let (x, y) = angle.sin_cos();
let (x, y) = ops::sin_cos(angle);
Vec2::new(x, y) * half_size
})
}
Expand Down
Loading