-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
Refactor bevy_mikktspace into idiomatic Rust #4932
Conversation
Yes please. Fundamentally from what I can see there's nothing in this algorithm that should require the use of |
I'm giving this the |
f1cdacf
to
1fc9bc1
Compare
1945aa0
to
e4e5b2c
Compare
bors try Failure seems to be spurious? Note to reviewers: This isn't used at all internally, so hopefully there are no behaviour changes, but I don't care significantly if there are :). Good future work is adding comparison fuzzing with the original C code's output (note: not the Rust port, since that definitely has UB). |
I would like to review this before it is merged. Just mentioning that so it doesn’t get merged before I’ve taken a look. I have not yet reviewed the PR so the following comments are not based on having seen the changes, just on awareness that this PR makes changes to numerically-sensitive code. I’m concerned about the numeric behaviour of any changes. I know @DJMcNab is aware of this concern and I trust that care has been taken. Still I feel it is easy to unintentionally change arithmetic behaviour. Ideally there would be a comprehensive set of regression tests for this kind of thing, as @DJMcNab suggests, comparing against the behaviour of the original the scope of verifying numeric results are the same. I suppose as we have the flight helmet model in the repo, one thing we could do is to generate tangents for that using the original C code and store those in the repo, and generate tangents using this code and compare. It wouldn’t be a set of tests targeted at edge/corner cases but it would at least test something.
I don’t understand this comment. What isn’t used internally? |
So what I mean is my priority is removing the unsound implemenation more than having exactly the same behaviour as the C code. As an examplel, the original C code is completely careless in their handling of The vast majority of the code doesn't do any floating point handling, and is just moving data around in hilariously evil ways. |
How do you define behaviour? It is only the numeric results that I care about being consistent. How it gets there, aside from performance, code maintenance, API ergonomics, etc, is secondary.
NaN/infinity aren’t always invalid in shader land. There is a trick used to discard vertices by setting their position to NaN for example. I’d be careful about deciding to explicitly check and handle NaNs unless it is very clear that a NaN at that point is invalid and has to be handled.
Right, totally down with making how the data is moved around be safe and rusty. And if indeed the float operations are an exact translation (including allowing NaNs or whatever, I guess, until proven that handling them differently is the correct thing to do) then this sounds great. Just saying this for the purpose of alignment. :) |
As an example, as far as I can tell, if there's a single vertex with infinite position, this line means that none of the vertices get merged. So, assuming that all positions are finite, what next? Following through the code, eventually you get to calling This is in C api rules, which best as I can tell is that any input which gets garbage out must be an illegal input. The only mention of NaN handling in mikktspace I can find is here, which prevents an infinite loop when they occur. In the original paper, the word Additionally, as best as I can tell from a quick check, weird values are forbidden in GLTF. Basically, I'm pretty confident that panicking in the prescense of NaN/infinity is fine. |
I'm not likely to drive this forward, so I'll defer to #9050 |
Objective
bevy_mikktspace
's use of unsafe is concerning.#[forbid(unsafe_code)]
Solution