-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
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
Move rotation interpolation to Curve3d and refactor baking #64212
Move rotation interpolation to Curve3d and refactor baking #64212
Conversation
Do you have a proposal or an issue that this closes? We ask that our contributors first document the problem or limitation that they experience, so that other contributors, users, and maintainers can find the best solution. A PR that adds new API needs a proposal, and a PR that fixes a bug needs a bug report. You would also need to squash all your commits into one before this can be merged (but this can be done after the code review). |
Thanks for the advice, this is my first effort to submit code on Github, and is still trying to figure out the proper procedure. I add a proposal. |
It often depends from project to project. We have our procedures explained in the documentation for contributors: |
43c27ab
to
e55b2a8
Compare
@TokageItLab I will look at this too. |
e55b2a8
to
15c5147
Compare
Something is odd. There are 6 ways to convert euler to quaternion. You only have 3. |
Because only those 3 are exposed in the original |
55aede0
to
37a811e
Compare
37a811e
to
fe23fb0
Compare
Is there anything blocking this now that the 2D equivalent has been merged? |
fe23fb0
to
96ae391
Compare
dd3d14f
to
c53faee
Compare
A major refactor of the sampling methods on baked points. The main changes are
Now this PR should be ready for review. I plan to start coding this proposal once this PR merged, as |
Ok, then it
I propose the comparison can be done by user between new build and original build, if the old behavior is indeed better, it can be implemented properly in following PR(move both data and behavior to Honestly this PR discussion is too long (arguably the longest per file? 130+ post for just 4 code files), it seems this part of system is too intricate for me. I propose we wrap it up here, or leave it to someone more capable. |
Let's keep the old behavior for now but keep the new TNB code somewhere so that it can be reused in a follow-up PR imho Also > artistic control isn't an issue here imho |
The actual discussion is not that much since most of the comments are code comment and variable name corrections and your responses to them. The length of the discussion is not the point, in refactoring it is important to be careful and to implement it correctly. Also, the stance of change the old behavior as a trial and then revert after seeing the response is basically not approved. We need to test and discuss whether it makes sense or not before merging. If you want to avoid discussion for tilt, it is best to keep the old behavior. Indeed, I don't like the old tilt's behavior, but I can't decide that the new tilt's behavior is fine or not yet. At least, if you remove the old tilt behavior here, we lose the ability to cover it. So it is best to keep the original behavior here, then in a later PR, implement the artistic control and change the old tilt behavior at the same time. |
389db3e
to
2ea259b
Compare
done |
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.
The comment should be if it is a long process where the function name alone does not describe the behavior or "the reason for the constant" or "the why not another implementation for here". Do not include your simple question.
Most of the problems seem to have been taken care of. After fixed comment, please put all your commits in one by squashing.
34f5364
to
77898bf
Compare
This commit makes the following major changes 1. Add "sample_baked_with_rotation()" to Curve3D, making it usable independently. A similar change was made to Curve2D previously. 2. Refactor the _bake() method on Curve3D, using Parallel Transport Frame instead of Frenet Frame. 3. Refactor the sample_* methods, including: i. Factor out common binary search code, following the DRY principe ii. sample_up_vector() interpolated up vector as part of rotation frame(posture) for consistancy and accuracy.
77898bf
to
5241464
Compare
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.
It made me confused since the variables and functions were not matching the actual behavior, but I think that most of problem has been removed and it becomes readable in some extent now. The behavior is not perfect, but it is better than before. Thank you for hard working :)
I approved this for now because we need to follow the Curve2D changes and merge this. Some improvements should be made in a follow-up PR later.
I leave some comments below on points that I could not determine on my own.
bool is_loop = true; | ||
// Loop smoothing only applies when the curve is a loop, which means two ends meet, and share forward directions. | ||
{ | ||
if (!points_ptr[0].is_equal_approx(points_ptr[point_count - 1])) { | ||
is_loop = false; | ||
} | ||
|
||
real_t dot = forward_write[0].dot(forward_write[point_count - 1]); | ||
if (dot < 1.0 - 0.01) { // Alignment should not be too tight, or it dosen't work for coarse bake interval | ||
is_loop = false; | ||
} | ||
} | ||
|
||
up_write[idx] = up; | ||
// Twist up vectors, so that they align at two ends of the curve. | ||
if (is_loop) { | ||
const Vector3 up_start = up_write[0]; | ||
const Vector3 up_end = up_write[point_count - 1]; |
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.
It seems that the rotations still don't perfectly match between progress 0 and 1.
Possibly, I guess the main cause is that the interval at the end of the bake is different from the other intervals. Yeah, now behavior is better than before, so I think it is fine for now, but there is room for improvement.
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.
Yes, I agree. From the picture I saw the tangents(blue arrows) is not aligned perfectly. Which should be problem in baking. I will investigate later.
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.
Should be fixed by #69043
Vector3 Curve3D::sample_baked_up_vector(real_t p_offset, bool p_apply_tilt) const { | ||
if (baked_cache_dirty) { | ||
_bake(); | ||
} | ||
|
||
// Validate: Curve may not have baked up vectors. | ||
ERR_FAIL_COND_V_MSG(!up_vector_enabled, Vector3(0, 1, 0), "No up vectors in Curve3D."); | ||
|
||
int count = baked_up_vector_cache.size(); | ||
if (count == 1) { | ||
return baked_up_vector_cache.get(0); | ||
} | ||
|
||
return up.rotated(axis, up.angle_to(up1) * frac); | ||
p_offset = CLAMP(p_offset, 0.0, get_baked_length()); // PathFollower implement wrapping logic. | ||
|
||
Curve3D::Interval interval = _find_interval(p_offset); | ||
return _sample_posture(interval, p_apply_tilt).get_column(1); |
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.
I don't know whether sample_baked_up_vector()
always needs forward_vector
. _sample_posture()
does spherical interpolation of the basis created from the baked up_vector
and unbaked forward_vector
inside it, but it seems to me that this is beyond the role of the function of the name sample_baked_up_vector()
.
Rather, since the only use of sample_baked_up_vector()
is for paths in CSGShape
, perhaps we can remove this and keep only sample_baked_with_rotation()
. But that include unnecessary processing, so I still think it is better to rename sample_baked_up_vector()
to sample_up_vector()
as a wrapper funtion of _sample_posture()
.
How do you think? @reduz
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.
created from the baked up_vector and unbaked forward_vector inside it
to not bake the forward_vector is just an optimization, because it is cheap to calculate on the fly. If performance is indeed an issue, baking cache for forward_vector can be add back easily.
since the only use of sample_baked_up_vector() is for paths in CSGShape
Another possibility is to remove sample_baked_up_vector()
altogether, and let CSGShape
use the rotation frame from sample_baked_with_rotation()
directly.
Currently the CSGShape
path mode calculate its own rotation frame
godot/modules/csg/csg_shape.cpp
Line 1963 in 324106b
Transform3D facing = Transform3D().looking_at(direction, current_up); |
It use the same method as
sample_baked_with_rotation()
(looking_at(tangent, up)
). So using rotation frame directly from sample_baked_with_rotation()
is equivalent, but have advantages for future: Let CSGShape path mode benefit from improvements on Curve3D for free, such as better tilt, bug fixes, performance optimization
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.
So I suggested in my comment above that CSGShape
use sample_baked_with_rotation()
and remove sample_baked_up_vector()
. But it include a process sample_baked()
which is not needed, so I more recommended renaming it to sample_up_vector()
. Or make sample_posture()
public and remove sample_baked_up_vector()
is another way.
In any case, the name sample_baked_up_vector()
seems strange for me because it is sampling something unbaked by _sample_posture()
internally.
The final decision on whether to rename it or not is left to @reduz or another experienced contributor.
Also thank you for all your time putting into this PR. Hope we can get to consensus faster in future PRs :) |
@YuriSizov is it possible to move this PR to 4.0 milestone? Considering the Curve2D counterpart has already been merged. |
Thanks! |
This change seems to have changed the behavior for Here is a screenshot of a curve with tilt 0 for all points before and after this was merged: My change rebased on top of 8ab3e73^ (immediately before the merge uploaded here ): My change rebased on top of 8ab3e73 : You can see the up vectors are 90 degrees from their previous location. EDIT: a better screenshot |
@xiongyaohua Might it be possible that normal is being baked instead up vector by mistake? I'm not sure since I haven't looked into rotating algorithm itself enough. In any case, the Path3D area is refactoring now, so if anyone find anything odd, we should open an issue and discuss it each time @Ademan. |
Related with PR #64043, PR #63956 there are two purpose of this PR:
The new implementation should be more stable. Although I test it for some cases, further testers are needed, as I mainly use Curve2D for current project.
Untitled.mov
Tested against examples in the following tickets:
48864
27137
60151