-
-
Notifications
You must be signed in to change notification settings - Fork 67
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Amazing! 😄 See my comment below for a potential improvement
Vec3::new(xz.x, y, xz.y) | ||
} | ||
}; | ||
Line::build(position, segments) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing I'm thinking... 🤔 Would it be easy to analytically compute normal and tangent vectors for each point? Because if so, we could add one extra parameter to add those channels and nodes like Extrude along curve
would work out of the box with catenary curves, which would be pretty cool.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that's pretty easy to compute. Would that go in Line::build
? If there's an example somewhere of filling in those channels I can add that tonight/tomorrow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's an example in resample_curve
(edit_ops.rs:1846
), but that one's probably a bit convoluted. The whole idea with mesh channels is to allow attaching arbitrary data to vertices, halfedges and faces. You would need something like:
// Create the channel, and fetch by id
let tangent_ch_id = mesh.channels.ensure_channel::<VertexId, Vec3>("tangent");
// Channels have interior mutability, hence the `read_*` and `write_*` variants to access them.
let mut tangent_ch = mesh.channels.write_channel(tangent_ch_id).unwrap();
// Then, you can use it like a map:
let v: VertexId = todo!("obtain it somehow");
tangent_ch[v] = Vec3::new(1.0, 2.0, 3.0);
dbg!(tangent_ch[v]);
Channels are like a sort of "loose" map in that you can always fetch from it even if you've never inserted a key before (and you get Default::default()
back) and you can always set a key as long as it's a valid vertex for the mesh. They're based on slotmap::SecondaryMap
.
As you say, a good place for this code would be the Line::build
function, you can create these channels right below the call to write_positions
(FYI, vertex positions are just one of the channels that are allocated by default in a mesh, there's nothinc special about them other than the read_positions
/ write_positions
convenience methods). The function could take two (perhaps optional?) functions for tangent and normal values. Feel free to refactor things a bit to make it fit, as I have the impression doing that might make the code a bit awkward 🤔
I'm not sure what we should do with other line constructors that don't have a well-defined notion of normals (like the regular Line
node, or Line from points
). In those cases, we can either compute some normals by picking an arbitrary direction like one of the 3 main axis, or else we could make the tangent / normal channels optional and not compute them for those constructors. I'm not sure how useful this sort of default would be.
Fixes "extrude along curve" and other operations for line/curve primitives. Also, add computed normals and tangents to catenary curve
66f9943
to
444bbe3
Compare
Had some git issues, but I think this PR is good to go now. Also, I'll comment that there's a mismatch in the defaults for circle and extrude along curve. The circle needs to be rotated first and the faces flipped on the extrude node to get what you expect. May be a larger issue so I didn't want to mess with it too much. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good 👍 Ready to merge!
After further exploration, I think there's something fishy with those normals 🤔. See how there's this unwanted rotation at the start that moves forward as I extend the curve? 2022-11-12.13-10-55.mp4This is the code that extrude along curve uses to rotate the cross section at let normal = normal_ch[v];
let tangent = tangent_ch[v];
dbg!(normal.dot(tangent));
let cotangent = normal.cross(tangent);
let (_, rotate, _) = glam::Affine3A::from_cols(
cotangent.into(),
normal.into(),
tangent.into(),
glam::Vec3A::ZERO,
) When using a regular Now that we have gizmos, I'm going to work on some API that lets us do some debug drawing to better see what's going on, I've been meaning to do that for a while. |
Also, add a fallback for when we can't find a solution for the x offset in the catenary.
Yeah, that looks like the tangent is wrong, I was getting that earlier but thought it was better. Fixed with some simpler code that I should have tried first. Also added a fix for when the endpoints line up vertically and the math stops working. catenary-tangents.mp4Let me know if you spot anything else weird. |
Amazing! Thanks for the hard work 😄 |
For #60