mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 20:53:53 +00:00
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:
parent
eb6e97c18e
commit
28faafdc41
1 changed files with 27 additions and 3 deletions
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue