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

Use true pitch/yaw/roll rotations without loss of precision by pgimeno #8019

Merged
merged 6 commits into from
Feb 7, 2019

Conversation

p-ouellette
Copy link
Contributor

@p-ouellette p-ouellette commented Dec 25, 2018

From https://gitlab.com/pgimeno/minetest/merge_requests/3/

Store the rotation in the node as a 4x4 transformation matrix internally (through IDummyTransformationSceneNode), which allows more manipulations without losing precision or having gimbal lock issues.

Network rotation is still transmitted as Eulers, though, not as matrix. But it will stay this way in 5.0.

Fixes #7927

EDIT by paramat: Applies implementation discussed from #7927 (comment) onwards.
Details #7927 (comment)

@ghost
Copy link

ghost commented Dec 25, 2018

Thanks for submitting it!

@paramat
Copy link
Contributor

paramat commented Dec 26, 2018

Thanks.
This needs careful consideration and is a complex issue, see linked issue.

@paramat paramat added Blocker The issue needs to be addressed before the next release. High priority Bugfix 🐛 PRs that fix a bug labels Dec 26, 2018
@paramat paramat added this to the 5.0.0 milestone Dec 26, 2018
@stujones11
Copy link
Contributor

This looks good to me and is pretty much the 'officially' endorsed solution to this common problem. While doing this is fine for your main game actor, my only minor concern would be the creation of an additional dummy scene node for every single game object.

I doubt that it will be a problem but we really should try to get some numbers on this.

@ghost
Copy link

ghost commented Dec 26, 2018

I doubt that it will be a problem but we really should try to get some numbers on this.

I don't notice any difference with a bunch of objects simultaneously visible, but I don't have a particularly slow computer. My measurement attempts have been hindered by total lack of vsync control. With normal vsync I get 60 fps; setting __GL_SYNC_TO_VBLANK=0 I get 62 FPS. I filled up my inventory and started digging, and got the scene below. No matter where I looked I got 62 FPS. Only when I looked at forests with lots of leaves, I got a drop in FPS, but that drop isn't related to the patch.
Edit: Ahh, got it, it was the MaxFPS. No noticeable difference.

@stujones11
Copy link
Contributor

stujones11 commented Dec 27, 2018

I don't have a particularly slow computer

I would consider a better test to be spawn 1000+ objects, with and without this PR and then compare memory usage and other vital stats.

@paramat
Copy link
Contributor

paramat commented Dec 27, 2018

Tested with my original boats patch #7395 (comment)
Rotation for the boat is now an intuitive 'intrinsic' yaw-pitch-roll.
Left-right for yaw, forward-back for pitch and jump-sneak for roll.

@paramat
Copy link
Contributor

paramat commented Dec 27, 2018

As the large majority of objects in MT will only use yaw (dropped items, most mobs), might there be benefit (would it even be possible?) in dividing objects into yaw-only and yaw-pitch-roll versions? Adding a new object property to select between those.

@stujones11
Copy link
Contributor

dividing objects into yaw-only and yaw-pitch-roll versions?

Although rather messy, we could simply have a boolean property to enable 6d rotation and only add the matrix node for those objects. Hopefully, this should not be necessary though.

@ghost
Copy link

ghost commented Dec 27, 2018

Yes, it would indeed get messy. A bunch of new methods would be necessary to abstract the operations that are currently performed sometimes on the object scene node and sometimes on the transformation node, so that they can work both with and without the latter transparently. That would make the patch larger and more invasive.

Considering that at some point, Irrlicht will fix this on their side (hopefully in not many years), keeping the patch as simple as possible will help reverting the changes when that happens.

As for memory and other vital stats, I'll defer testing to whoever knows what and how to measure.

@paramat
Copy link
Contributor

paramat commented Dec 27, 2018

Ok thanks, i was suspecting it would create too much mess, and there may not be performance issues anyway.

src/util/numeric.cpp Show resolved Hide resolved
src/util/numeric.cpp Show resolved Hide resolved
src/util/numeric.h Show resolved Hide resolved
src/util/numeric.h Show resolved Hide resolved
@ghost
Copy link

ghost commented Jan 3, 2019

Added unit tests. @pauloue could you fetch/push please?

Pedro Gimeno added 3 commits January 3, 2019 19:49
Store the rotation in the node as a 4x4 transformation matrix internally (through IDummyTransformationSceneNode), which allows more manipulations without losing precision or having gimbal lock issues.

Network rotation is still transmitted as Eulers, though, not as matrix. But it will stay this way in 5.0.
Also add a comment explaining the new node and its limitations.
@p-ouellette
Copy link
Contributor Author

There was a conflict in networkprotocol.h. That's the reason for the force push. If that's a problem you can do the rebase on your branch.

@ghost
Copy link

ghost commented Jan 3, 2019

Thanks, yes I had a rebased version ready locally, waiting for someone to ask me to rebase. I wanted to remove a line there actually, so I've force-pushed my gitlab branch. You may need to delete your local branch before fetching, not sure.

src/client/content_cao.cpp Outdated Show resolved Hide resolved
nerzhul
nerzhul previously requested changes Jan 3, 2019
Copy link
Member

@nerzhul nerzhul left a comment

Choose a reason for hiding this comment

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

except minor changes, can is good for me. Anyway untested

src/client/content_cao.cpp Outdated Show resolved Hide resolved
@paramat
Copy link
Contributor

paramat commented Jan 4, 2019

One thing i need to test is using a "cube" or "item" visual entity and checking the correct face is treated as the 'front'.

@ghost
Copy link

ghost commented Feb 1, 2019

I've tested the dynamic updates under the same conditions. Without limiting the number of entities, the results were as follows: 42-44 FPS on master, 38-40 FPS on this branch. The numbers oscillated, which is expected due to interference between the frequencies of the server ticks and the client frames. As a consequence, this result is a bit less accurate. The extra calculation time is in this case 1/39 minus 1/44, approx. 2.9 ms for 1023 entities. Given the bigger measurement error, I think that sounds about the same. That matches my expectations.

The FPS I expected was actually worse; my calculation was a decrease by a factor of 41.8/(41.8+11.1) = 79% which means 33 FPS (all numbers are approximate). Perhaps the server isn't sending all updates to the client due not all entities being in front of the player. The camera wasn't in the same position as the previous test, even though it was in the same position during this testing; maybe that affected the results somehow too.

I'm satisfied with these results, so I'll consider it tested ant call it a day.

(Edited blunder with the way I presented the numbers, apologies)

@paramat
Copy link
Contributor

paramat commented Feb 2, 2019

Performance seems good, it tests well, what this implements is good and seems a widely accepted solution, lots of attention which i appreciate. So once i check codestyle i think all this counts for something and i will probably +1.
However, i do not completely understand some aspects, so i will request that the core dev who gives the 2nd +1 does.

@rubenwardy
Copy link
Member

I'm so happy to see so many tests

How much testing has this had, in practice? Using old worlds and new, on different clients, etc

@ghost
Copy link

ghost commented Feb 3, 2019

I've tested only in new worlds. I don't use MT5 to play, so I can't say it's field-tested. I haven't tried migrating old worlds. However, the protocol change introduced by this patch only affects entities that have a nonzero Z rotation, and is compatible otherwise. Therefore the only potential problem I foresee is with those people using a version which includes #7395 and #7989 and who already used a rotation with a Z component != 0. The existing entities in those conditions (if there are any out in the field, which I doubt) will have a different rotation; the rest will keep compatibility. This PR does not affect those migrating from stable-0.4.

@ghost
Copy link

ghost commented Feb 3, 2019

In case it helps understanding the PR, here's a diagram of what the patch implements:


Without patch:
52180232-f9971b80-27e3-11e9-8eef-543e6d7f3d6bind


With patch:
52180234-0287ed00-27e4-11e9-8854-e309cefebd62ind

@paramat
Copy link
Contributor

paramat commented Feb 4, 2019

Looked through code, partially understand it 👍

@ClobberXD
Copy link
Contributor

ClobberXD commented Feb 5, 2019

The diagram helps a lot. I can understand how it works now. Neat. :)

But upon looking through the changes, I notice that the rotations follow a different coordinate system (X: forward-backward, Y: left-right, Z: up-down), whereas all spatial vectors in MT follow the right-handed system (X: left-right, Y: up-down, Z: forward-backward). This would cause quite a bit of confusion for modders. Is there a reason why rotations need to follow the proposed coordinate system?

@ghost
Copy link

ghost commented Feb 5, 2019

@ClobberXD There seems to be a confusion. The code is designed to be able to work with MT's axis conventions. The convention you point out is that of the native Irrlicht ISceneNode rotations, which caused #7927 (see there for details) and the whole problem that this PR is aimed to work around. Note how the ISceneNode rotation is kept at 0 with the patch, so it doesn't interfere with the different, Minetest-friendly convention introduced by setPitchYawRoll().

I may have made a mistake, though. If so, could you please let me know which specific part of the code uses Z for up?

(edit: wrong issue number fixed)

@ghost
Copy link

ghost commented Feb 5, 2019

@ClobberXD I wonder if the source of confusion is that this patch is NOT in the 5.0.0 pre-release even if there was some discussion about including it. The 5.0.0 pre-release does behave the way you're pointing out.

(As an aside, in case you missed the edit, I wrote the wrong issue number above, the correct one is #7927)

@paramat
Copy link
Contributor

paramat commented Feb 5, 2019

I notice that the rotations follow a different coordinate system (X: forward-backward, Y: left-right, Z: up-down)

That's a confusing way to refer to rotations, how can a rotation be 'forward-backward' and what does that mean? Rotations refer to axes.
Can you specify a part of this code you are concerned about?

@ClobberXD
Copy link
Contributor

ClobberXD commented Feb 6, 2019

@pgimeno Looks like I was indeed confused, and I misinterpreted stuff. Sorry for the trouble. Great work! 👍

That's a confusing way to refer to rotations, how can a rotation be 'forward-backward' and what does that mean? Rotations refer to axes.

I was referring to the axes and not the rotations itself, but I guess that doesn't matter now. :)

@paramat
Copy link
Contributor

paramat commented Feb 7, 2019

I'll merge this once that's done.

@ghost
Copy link

ghost commented Feb 7, 2019

@pauloue could you update it please?

@p-ouellette
Copy link
Contributor Author

Updated

@paramat paramat merged commit d5456da into minetest:master Feb 7, 2019
@paramat paramat removed this from PR in Minetest 5.0.0 blockers Feb 7, 2019
@ghost
Copy link

ghost commented Feb 7, 2019

Big thanks to @pauloue for hosting this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Blocker The issue needs to be addressed before the next release. Bugfix 🐛 PRs that fix a bug Feature ✨ PRs that add or enhance a feature High priority >= Two approvals ✅ ✅
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants