Skip to content

Commit

Permalink
Fix torus normals (bevyengine#4520)
Browse files Browse the repository at this point in the history
# Objective

Fix wonky torus normals.

## Solution

I attempted this previously in bevyengine#3549, but it looks like I botched it. It seems like I mixed up the y/z axes. Somehow, the result looked okay from that particular camera angle.

This video shows toruses generated with
- [left, orange] original torus mesh code
- [middle, pink] PR 3549
- [right, purple] This PR

https://user-images.githubusercontent.com/200550/164093183-58a7647c-b436-4512-99cd-cf3b705cefb0.mov
  • Loading branch information
rparrett authored and ItsDoot committed Feb 1, 2023
1 parent 2b5081c commit a620724
Showing 1 changed file with 7 additions and 11 deletions.
18 changes: 7 additions & 11 deletions crates/bevy_render/src/mesh/shape/torus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,16 @@ impl From<Torus> for Mesh {
for side in 0..=torus.subdivisions_sides {
let phi = side_stride * side as f32;

let x = theta.cos() * (torus.radius + torus.ring_radius * phi.cos());
let z = theta.sin() * (torus.radius + torus.ring_radius * phi.cos());
let y = torus.ring_radius * phi.sin();

let tan_ring = Vec3::new(
theta.cos() * phi.sin() * -1.0,
theta.sin() * phi.sin() * -1.0,
phi.cos(),
let position = Vec3::new(
theta.cos() * (torus.radius + torus.ring_radius * phi.cos()),
torus.ring_radius * phi.sin(),
theta.sin() * (torus.radius + torus.ring_radius * phi.cos()),
);
let tan = Vec3::new(theta.sin() * -1.0, theta.cos(), 0.0);

let normal = tan.cross(tan_ring).normalize();
let center = Vec3::new(torus.radius * theta.cos(), 0., torus.radius * theta.sin());
let normal = (position - center).normalize();

positions.push([x, y, z]);
positions.push(position.into());
normals.push(normal.into());
uvs.push([
segment as f32 / torus.subdivisions_segments as f32,
Expand Down

0 comments on commit a620724

Please sign in to comment.