Skip to content
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

fix computeFaceNormal: use corner whose angle is closest to right angle for cross product #131

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

henkson
Copy link

@henkson henkson commented Dec 21, 2023

This change provides a fix for issue #130.

  • adding a method angle that calculates the angle between 2 Vector3 objects
  • modifying the Mesh.computeFaceNormal method: verify the angles of all face vertices, and use the vertex whose angle is the closest to a right angle (90°). This makes the cross product numerically more stable.

@henkson
Copy link
Author

henkson commented Dec 21, 2023

Benchmarking the code with over 5000 test meshes doesn't show any performance impact.

static float angle(const Vector3 &a, const Vector3 &b)
{
const Vector3 c = cross(a, b);
return abs(atan2(length(c), dot(a, b)));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you want you can try using a polynomial fit for this. it musnt be precise. look how cute it is when I try the montreal university fit (Sreeraman Rajan et al.)
image

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not so sure, atan2 should give results in the range [-pi, pi], while atan gives results in the range [-pi/2, pi/2].
Apart from that, that smells like premature optimization imo ("no visible slowdown").

Copy link

@siliconvoodoo siliconvoodoo Nov 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes it is premature optimization. don't touch it, the test showed it's not necessary

@siliconvoodoo
Copy link

siliconvoodoo commented Nov 5, 2024

bunch of warnings you could cleanup

1>xatlas\source\xatlas\xatlas.cpp(821,12): warning C4244: 'return': conversion from 'double' to 'float', possible loss of data
1>xatlas\source\xatlas\xatlas.cpp(2726,26): warning C4244: 'initializing': conversion from 'double' to 'float', possible loss of data
1>xatlas\source\xatlas\xatlas.cpp(2726,21): warning C4244: 'initializing': conversion from 'double' to 'const float', possible loss of data
1>xatlas\source\xatlas\xatlas.cpp(2727,26): warning C4244: 'initializing': conversion from 'double' to 'float', possible loss of data
1>xatlas\source\xatlas\xatlas.cpp(2727,21): warning C4244: 'initializing': conversion from 'double' to 'const float', possible loss of data
1>xatlas\source\xatlas\xatlas.cpp(2728,26): warning C4244: 'initializing': conversion from 'double' to 'float', possible loss of data
1>xatlas\source\xatlas\xatlas.cpp(2728,21): warning C4244: 'initializing': conversion from 'double' to 'const float', possible loss of data

@siliconvoodoo
Copy link

I tried it. no visible slowdown. LGTM

@mifth
Copy link

mifth commented Nov 5, 2024

Should Vectors be normalized before the cross product?

@mifth
Copy link

mifth commented Nov 5, 2024

@siliconvoodoo @henkson
I've found that there is kPi2 variable which I think you should use instead of M_PI_2. The point of the lib is to use all internal things.

@mifth
Copy link

mifth commented Nov 5, 2024

And you probably need to remove the #define _USE_MATH_DEFINES.

@henkson
Copy link
Author

henkson commented Nov 5, 2024

@siliconvoodoo @henkson I've found that there is kPi2 variable which I think you should use instead of M_PI_2. The point of the lib is to use all internal things.

@mifth
We can't use kPi2 because that is equal to 2 * PI and we need PI / 2 here.
I do understand your "internal things" remark though, I can add a new variable. Do you have a suggestion for its name? (I have no idea where the k prefixes comes from. M_ probably stands for "math"?)

And you probably need to remove the #define _USE_MATH_DEFINES.

That was probably only needed because I used those M_PI and M_PI_2 variables. (Correct? I'm not really a C/C++ developer, and it's almost a year since I wrote this...)

@mifth
Copy link

mifth commented Nov 5, 2024

Oh, right! A new variable is needed. About the name I would leave it to you if you don't mind. I believe something like kPi_YourNewName. :)

Yeah it seems the #define _USE_MATH_DEFINES was used for the M_PI_2 only,

@mifth
Copy link

mifth commented Nov 5, 2024

Just have got in my mind. What do you think about kPi_Half?

@siliconvoodoo
Copy link

the k prefix is just one of usual conventions to denote a hard constant. (usually the type that get inlined at code generation and they have no ODR existence)

@mifth
Copy link

mifth commented Nov 7, 2024

I've tested your code with a 200000 triangles mesh. It looks pretty healty. 15-17 seconds both versions. Your version sometimes works even faster (-1 second). I guess it's because of less negative triangles.

image
image
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants