-
Notifications
You must be signed in to change notification settings - Fork 616
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
Implement turntable camera roll
programmatically and clarify transformation docstrings
#2352
Conversation
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.
Looks good. Thanks for putting this together. I think this makes sense. I'm not really sure why the documentation was so wrong. I have a couple requests before merging this:
- Could you remove your test script.
- Could you add a proper test to the unit tests. Probably here: https://github.com/vispy/vispy/tree/main/vispy/scene/cameras/tests
- Could you restructure the docstrings for the properties to be more PEP8 compliant where the first line is a single sentence with an imperative verb, then a blank line, then any additional description. For example:
def my_method(self, x, y, z):
"""Get some value by doing stuff.
Further description.
"""
... code ...
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.
Beautiful! Thank you. One small change request for better test output on failure.
Co-authored-by: David Hoese <david.hoese@ssec.wisc.edu>
@djhoese thanks for the advice and quick review! I just undid some auto-formatting changes that were committed. This PR should be okay for a second look! |
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.
🎉
@brisvag or @almarklein do you want to give one more review and then we can merge this.
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.
Looks good to me too, assuming tests pass!
Looks like two tests failed in at least one of the environments:
The last one I suppose could just be a precision error brought on by the additional multiplications with handling |
Should be able to make the tests pass by adding the vispy/vispy/scene/cameras/turntable.py Line 142 in fcc0139
although I believe this means that the rotation around the x-axis ( elevation ) is in the opposite sense to the other two rotations (roll and azimuth ) around their respective axes. What do you think?
Alternatively all transformations could be performed in the same sense as |
I have no experience with the 3D cameras so I'm not sure I should make a decision. @almarklein @brisvag ? |
I guess we should strive to have everything rotate with the same handedness; we have to becareful changing this stuff though, cause it's gonna break for everyone using it :/ Is there a way we can somehow deprecate it and let people "opt in"? |
Would a |
So for one release we do that, and for the next one we have to deprecate |
I think that would be a safe way to implement the change and would give users warning about it. Happy to implement this if you like the idea! |
I'm curious if @rougier or @almarklein know why the camera's |
I'm not sure. If this is only for how a mouse move rotates the camera, than one might view it more as a UX problem than inherent mathematical way of working, and a difference would be fine, I suppose? |
@harripj do you have a quick code example to test out exactly what the difference entails in UX terms? |
You can test out the UX differences by running this script (based on the failing test @djhoese mentioned above: #2352 (comment)): from types import MethodType
from vispy import io, scene
from vispy.util import transforms
def test_perspective_render():
canvas = scene.SceneCanvas(size=(120, 200), show=True)
grid = canvas.central_widget.add_grid()
imdata = io.load_crate().astype('float32') / 255
for i in range(2):
v = grid.add_view(row=i, col=0, border_color='white')
v.camera = 'turntable'
v.camera.fov = 50
v.camera.distance = 30
v.camera.elevation = 30
v.camera.roll = 0
v.camera.azimuth = 40
if not i:
def _old_rotation_tr(self):
"""Return a rotation matrix based on camera parameters"""
up, forward, right = self._get_dim_vectors()
matrix = (
transforms.rotate(self.elevation, -right)
.dot(transforms.rotate(self.azimuth, up))
.dot(transforms.rotate(self.roll, forward))
)
return matrix
v.camera._get_rotation_tr = MethodType(_old_rotation_tr, v.camera)
else:
def _new_rotation_tr(self):
"""Return a rotation matrix based on camera parameters"""
up, forward, right = self._get_dim_vectors()
matrix = (
transforms.rotate(self.elevation, right)
.dot(transforms.rotate(self.azimuth, up))
.dot(transforms.rotate(self.roll, forward))
)
return matrix
v.camera._get_rotation_tr = MethodType(_new_rotation_tr, v.camera)
image = scene.visuals.Image(imdata, grid=(4, 4))
image.transform = scene.STTransform(translate=(-12.8, -12.8),
scale=(0.1, 0.1))
v.add(image)
return canvas
if __name__ == "__main__":
canvas = test_perspective_render()
canvas.app.run() After running this I see why the transform matrix is constructed as it is (with Further, the roll |
Sounds great! Thanks for the example, very clear. Indeed it seems we want to keep the old implementation (and maybe add a comment or docstring to explain why and point to this PR for future reference). |
@harripj do you have time to push over the line? The remaining test failure should be fixable as you said by increasing the tolerance a bit! |
@brisvag sorry for the delay, I have been busy lately. I will take another look at this over the weekend! |
roll
programmatically and clarify transformation docstrings
@brisvag I have had another look over this and updated the tests. Effectively this PR clarifies the The UI interaction is such that |
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.
Looks good to me from the small amount I understand of the conversation here. I had two comments about the docstrings.
vispy/scene/cameras/turntable.py
Outdated
rotation of the camera around the scene z-axis according to the | ||
right-hand screw rule. |
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.
Can/should you mention what the camera "sees" when azimuth is at 0 degrees as it did in the old docstring?
@djhoese thanks for reviewing, I have updated the docstrings with your suggestions. Hopefully the information comes across more clearly now. |
Co-authored-by: David Hoese <david.hoese@ssec.wisc.edu>
This looks good to me. Let's merge it. The build website failing is a known issue and I doubt your PR is causing any issues. Thanks again for this @harripj! |
As discussed in #2279 the docstrings of
elevation
,azimuth
, androll
appear to be misleading forTurntableCamera
. This PR aims to address this and also implementsroll
functionality. TheTurntableCamera._get_rotation_tr()
function has been updated so all three transformations represent consistent right-hand rotations around the respective axes.This PR may be missing some nuance as to the way camera rotations are defined in VisPy, for example rotations of the camera around a static scene or vice-versa, or as to why
roll
was not implemented in the first place. regarding the former point,I have written this PR in the first sense.Any help or guidance appreciated! Thanks!