Fix tiny seam in Annulus geometry. (#14913)

# Objective

There is a tiny seam at the top of the annulus caused by normal
floating-point error in calculating the coordinates. When generating the
last pair of triangles, given `n == i` then `(TAU / n) * i` does not
equal `TAU` exactly.

Fixes https://github.com/komadori/bevy_mod_outline/issues/42

## Solution

This can be fixed by changing the calculation so that `(TAU / n) * (i %
n) == 0.0`, which is equivalent for trigonometric purposes.

## Testing

Added the unit test
`bevy_render::mesh::primitives::dim2::tests::test_annulus`.
This commit is contained in:
Robin KAY 2024-08-25 15:11:58 +01:00 committed by GitHub
parent eb6e97c18e
commit 28faafdc41
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -598,7 +598,7 @@ impl MeshBuilder for AnnulusMeshBuilder {
let start_angle = FRAC_PI_2;
let step = std::f32::consts::TAU / self.resolution as f32;
for i in 0..=self.resolution {
let theta = start_angle + i as f32 * step;
let theta = start_angle + (i % self.resolution) as f32 * step;
let (sin, cos) = theta.sin_cos();
let inner_pos = [cos * inner_radius, sin * inner_radius, 0.];
let outer_pos = [cos * outer_radius, sin * outer_radius, 0.];
@ -1005,9 +1005,33 @@ impl From<Capsule2d> for Mesh {
#[cfg(test)]
mod tests {
use bevy_math::primitives::RegularPolygon;
use bevy_math::{prelude::Annulus, primitives::RegularPolygon, FloatOrd};
use bevy_utils::HashSet;
use crate::mesh::{Mesh, VertexAttributeValues};
use crate::mesh::{Mesh, MeshBuilder, Meshable, VertexAttributeValues};
fn count_distinct_positions(points: &[[f32; 3]]) -> usize {
let mut map = HashSet::new();
for point in points {
map.insert(point.map(FloatOrd));
}
map.len()
}
#[test]
fn test_annulus() {
let mesh = Annulus::new(1.0, 1.2).mesh().resolution(16).build();
assert_eq!(
32,
count_distinct_positions(
mesh.attribute(Mesh::ATTRIBUTE_POSITION)
.unwrap()
.as_float3()
.unwrap()
)
);
}
/// Sin/cos and multiplication computations result in numbers like 0.4999999.
/// Round these to numbers we expect like 0.5.