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

Tilt correction wrong if up != Vec3::Y #40

Closed
unpairedbracket opened this issue Feb 1, 2024 · 5 comments
Closed

Tilt correction wrong if up != Vec3::Y #40

unpairedbracket opened this issue Feb 1, 2024 · 5 comments

Comments

@unpairedbracket
Copy link

I think there's an error here: the tilted_up vector should be calculated as the tracked rotation applied to the y-axis rather than to self.up:

let tilted_up = ctx.tracker.rotation.mul_vec3(self.up);
let rotation_required_to_fix_tilt = Quat::from_rotation_arc(tilted_up, self.up);

The rotation_required_to_fix_tilt line makes sense - the desired "equilibrium" position is that where tilted_up == self.up. However, computing tilted_up as tracker.rotation * self.up means this condition becomes self.up = tracker_rotation * self.up, so the resulting equilibrium character transform is a rotation around self.up (in world-space) rather than a rotation of the "character-space" up vector (the y-axis) onto the desired world-space up vector self.up.

This leads to some odd-looking effects in-game when rotating the desired_forward direction of a character with self.up set to the normal of an angled floor.

Changing line 282 to

let tilted_up = ctx.tracker.rotation.mul_vec3(Vec3::Y);

solved these issues for me in local testing.

Hopefully this makes sense and I'm not just misinterpreting the intended usage of the up vector or something. Happy to open a PR if you'd prefer but that felt a bit overkill for a +/- 7-character proposed change

@idanarye
Copy link
Owner

idanarye commented Feb 1, 2024

Originally up was accompanied by another field - forward - and together they decided the orientation - which directions are considered up and the forward. They were both part of the configuration struct - unlike desired_forward, which was part of the controls struct.

When I did the big refactor of version 0.10, I did many changes - two of them I think are relevant to the confusion:

So if previously it was clearer that up as a similar purpose to forward - now it looks like it has a similar purpose to desired_forward. I think what you need is a desired_up field - which Tnua does not currently have.

The current up is not "where the head should be facing" - it's "which direction is considered as 'up'". For example - that's the direction opposite to the gravity. I think (didn't actually test this) that if you change it it'll cause problem because the spring force will no longer be parallel to the gravity.

Maybe I really should replace up with a proper desired_up that has the correct semantics...

@idanarye
Copy link
Owner

idanarye commented Feb 1, 2024

Now that I think about it - maybe the up direction should be set from the gravity? Instead of actions getting it from the basis, I can add it to the context and both basis and action will get it from there.

As for the desired_up - currently the ray's cast direction is affected by the rotation, which is not that noticeable but a desired_up will make it noticeable. I assume that even if the character is tilted by desired_up we still want to cast the ray straight down?

@rltvty
Copy link

rltvty commented Sep 16, 2024

I think I'm encountering a similar issue. I've been adjusting gravity in my world to be a line from my character to the center of the globe (origin), but my character wants to stand upright to Vec3::Y no matter what I do.

Is there a way I can change the up direction when I'm also adjusting gravity? I'd assume I just set it to the opposite of the gravity direction.

@rltvty
Copy link

rltvty commented Oct 13, 2024

Awesome, thanks for this fix!

Note that I'm close on having an update to the demo that allows you to switch between the flat world and a spherical world.

@idanarye
Copy link
Owner

@rltvty When you change the gravity to fit the player's position, what happens to the other rigid bodies? I assume your spherical world is small enough to have a noticeable curve. but AFAIK both Rapier and Avian only support a uniform gravity...

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

No branches or pull requests

3 participants