-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Bug fix: applying camera up.z vector at scene init #3256
Conversation
src/plots/gl3d/index.js
Outdated
@@ -51,6 +51,14 @@ exports.plot = function plotGl3d(gd) { | |||
scene = sceneLayout._scene; | |||
|
|||
if(!scene) { | |||
if(fullLayout[sceneId].camera.up.z !== 1 && | |||
fullLayout[sceneId].dragmode === 'turntable') { | |||
fullLayout[sceneId].dragmode = 'orbit'; |
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.
Would be better to do this in supplyDefaults
Not sure where we ensure ||up||===1
but it doesn't look like that's done in supplyDefaults
, so I guess at that point we might need a more complicated test (up.x || up.y || up.z < 0
perhaps?)
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 like the idea of having more complicated test as you mentioned. On the other hand I was wondering that it is now rather difficult for the users to compute and pass z vector components. Could we add a function to normalize user inputs for this vector before reaching there too?
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.
Only the direction of up
matters, right? So feels to me like we shouldn't require it to be normalized at all. If the user passes in (0,0,0) we should revert to (0,0,1), otherwise seems to me we should normalize it for our own use but leave the un-normalized value in layout
and fullLayout
.
@archmoj I like this solution (subject to the comment above). BTW, I notice a related issue: if you've set the plot in |
"x": 1, | ||
"y": 0, | ||
"x": 0, | ||
"y": 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.
So... gl3d_ibm_plot
has the old (verrrry old) camera format, and converts to the new format with a tilted up
, and you allowed it to shift into orbit
mode; that's great. And gl3d_surface_lighting
you converted to the new camera format and turntable-compatible up
, so the image changed because it's somewhat different from the output of the previous old->new conversion; also great.
But what's going on with gl3d_snowden_altered
? The image didn't change, but the change you made to up
is not to {x: 0, y: 0, z: 1}
so I'd have expected the image to change, since now it will render in orbit mode.
@@ -140,7 +140,7 @@ module.exports = { | |||
valType: 'enumerated', | |||
role: 'info', | |||
values: ['orbit', 'turntable', 'zoom', 'pan', false], | |||
dflt: 'turntable', | |||
dflt: 'orbit', |
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.
Hmm. I would prefer removing the dflt
key entirely - as the default value is now dynamic.
Could you also add some info in the description
about the new orbit-vs-turntable logic?
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 updated the description. Thanks @etpinard for the note. I will give removing dflt
a try.
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.
Once I tried to remove dragmode.dflt
, the default behaviour for drag using right-click (orbit/turntable) is not activated.
So we may keep it there.
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.
You need to pass the dynamic default to dragmode
here:
plotly.js/src/plots/gl3d/layout/defaults.js
Line 141 in c9eed54
coerce('dragmode', opts.getDfltFromLayout('dragmode')); |
getDfltFromLayout
is part of it but then there's the dynamic default based on camera
. I don't think you want to be altering sceneIn.dragmode
with enableTurnTable
, you just want to be setting the dynamic default. The logic is something like:
- If
getDfltFromLayout
returns a value, use that. - If not but the user provides a
camera
that's not{x: 0, y: 0, z: >0}
dfltDragmode='orbit'
- If neither of those,
dfltDragmode = 'turntable'
- Then you call
coerce('dragmode', dfltDragmode
) so the user can still explicitly provide whatever. - The only case that's still weird at that point is if the user explicitly says
dragmode: 'turntable', camera: {up: {not z-up}}
. My inclination at that point is to setsceneOut.camera.up
(and NOTsceneIn.camera.up
) to{x: 0, y: 0, z: 1}
. That won't change the behavior - the user might still wonder whyup
is not being honored - but at least it would raise an alarm if you callPlotly.validate
.
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.
Thanks @alexcjohnson, I will modify it to be this way.
@@ -394,7 +394,7 @@ describe('Test gl3d plots', function() { | |||
|
|||
it('@gl should be able to reversibly change trace type', function(done) { | |||
var _mock = Lib.extendDeep({}, mock2); | |||
var sceneLayout = { aspectratio: { x: 1, y: 1, z: 1 } }; | |||
var sceneLayout = { aspectratio: { x: 1, y: 1, z: 1 }, dragmode: 'turntable' }; |
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.
Why did you need to change this? I'm fearing a breaking change here.
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.
In order to set turnable
the default behaviour the function needs to add the dragmode
attribute to the sceneLayout.
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 without setting dragmode: 'turntable'
here, it would default to 'orbit'
?
What are the camera
settings in this case?
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.
@etpinard notice this isn't a setting, it's an expectation. But I agree, we shouldn't be mutating the input scene
, per my comment above
|
||
if(!x || !y || !z) { | ||
dragmode = 'turntable'; | ||
} else if(z / Math.sqrt(x * x + y * y + z * z) > 0.999) { |
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.
This PR is getting better by the minute. Thanks for your efforts @archmoj
Now, would there be a way to tweak this condition such that gl3d_ibm-plot
and gl3d_surface-lighting
still default to dragmode: 'turntable'
?
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.
Good point @etpinard. Let me check.
@@ -114,7 +114,7 @@ exports.cleanLayout = function(layout) { | |||
scene.camera = { | |||
eye: {x: eye[0], y: eye[1], z: eye[2]}, | |||
center: {x: center[0], y: center[1], z: center[2]}, | |||
up: {x: mat[1], y: mat[5], z: mat[9]} | |||
up: {x: 0, y: 0, z: 1} // we just ignore calculating camera z up in this case |
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.
Previous calculations of camera.up
for gl3d_surface-lighting
& gl3d_ibm-plot
didn't set up vector close to [0,0,1].
I thought we may ignore camera z up if cameraposition
depreciated setting is used.
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.
Nice solution.
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.
... and I presume the gl3d_opacity-surface.png
baseline changed because of 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.
Ignore that last comment. I didn't see #3256 (comment)
Thanks!
Also concerning the changes of 'gl3d_opacity-surface |
], | ||
1.8771354322421991 | ||
] | ||
}, |
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 thought this might not be necessary. If one wants to enable cameraposition
it is required to use "scene"
instead of "undefined"
! Also now I am curious about this mock & why it was named weirdness
? Also if we could possibly remove it or reduce the width/height.
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.
Wow. Thanks for fixing this. That undefined
shouldn't be there.
Very nice fix. 💃 |
interaction between previous changes in this PR and #3256
Fixes #2425 by seting
dragmode: 'orbit'
at init time to allow tilted camera z vectors and then possibly switch toturntable
mode as used to be desired default user mode.Background: in plotly.js
dragmode: 'turntable'
was applied as the default camera behaviour which is desirable for most cases and it modifies & locks camera z-axis rotation. However in certain cases when the user had specified camera z-axis this value was ignored at the start.The first approach applied here was to try to turn on
dragmode: 'orbit'
in those edge cases. The prototypes was working interactively but that introduced new side-effects and required complicated changes.On the other hand the second approach applied is to simply set
orbit
as the default and then switch toturntable
mode in all cases where the camera.z.up vector is different from being upwards i.e. [0,0,1].@etpinard
@alexcjohnson