-
-
Notifications
You must be signed in to change notification settings - Fork 3.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
Specification change for ortho() and frustum(), and implementation of scaling in orbitControl() of ortho() #6111
Specification change for ortho() and frustum(), and implementation of scaling in orbitControl() of ortho() #6111
Conversation
Make sure cameraFar and cameraNear are properly changed when calling ortho() and frustum(). Also change frustum() defaults. In addition, change y in frustum's projection matrix to -y. Match other projection matrices.
Even if you call orbitControl() with ortho(), you can still zoom in and out with the mouse wheel. Note that although it is no longer just "radius", we will not rename it to avoid confusion.
Due to the change in the specification of frustum(), the values of the projection matrix are different, so I also modified the unit test.
This is probably due to the fact that 0 is not negative.
Right, if you edit the doc comment there, when we release a new p5 version, it'll be reflected in the docs on the website. If you want to test a docs change locally, you can run |
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 work! A few minor comments so far that might make the code easier for future maintainers and contributors to understand.
Also, maybe we should add a unit test for the zooming behaviour in orbitControl
? So that we can assert that the projection matrix only changes for ortho cameras
src/webgl/interaction.js
Outdated
const mouseWheelSign = (this._mouseWheelDeltaY > 0 ? 1 : -1); | ||
const deltaRadius = mouseWheelSign * sensitivityZ * zoomScaleFactor; | ||
this._renderer._curCamera._orbit(0, 0, deltaRadius); | ||
// if ortho, scale change. |
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.
For future contributors, it's probably worth elaborating a little bit here about why this is necessary (ortho cameras don't make far things smaller, so just moving the camera wouldn't result in any visual change)
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.
Certainly, the projection matrix is only manipulated when performing orthogonal projection, so an explanation is necessary...
For example, ”For orthogonal projection, the elements of the projection matrix must be changed so that the scaling is 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.
I think that's a good start, although it would also be good to explain why scaling is necessary at all for ortho cameras (so, why just moving the camera isn't sufficient)
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 see, I'm sure it would be easier to explain the reason for the change... how about this?: "In orthogonal projection, the scale does not change even if the distance to the gaze point is changed, so the projection matrix needs to be modified."
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.
sounds great, thanks!
src/webgl/interaction.js
Outdated
const deltaRadius = mouseWheelSign * sensitivityZ * zoomScaleFactor; | ||
this._renderer._curCamera._orbit(0, 0, deltaRadius); | ||
// if ortho, scale change. | ||
if (uP[15] !== 0) { |
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 find, I didn't realize that ortho
was the only one that has a 1 in that corner!
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 had to think about that. It would be nice if it could be determined by a flag or something else that it is an orthogonal projection, but "cameraType" cannot do so (ortho and frustum are the same, "custom"), so I decided to rely on the components.
src/webgl/interaction.js
Outdated
@@ -93,14 +93,18 @@ p5.prototype.orbitControl = function(sensitivityX, sensitivityY, sensitivityZ) { | |||
|
|||
const zoomScaleFactor = 0.02; | |||
const scaleFactor = this.height < this.width ? this.height : this.width; | |||
const uP = this._renderer.uPMatrix.mat4; |
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.
Do you think maybe we should edit this._renderer.uPMatrix.mat4
directly instead of making a new variable referencing the same object? The result is the same either way, but it might be clearer to readers that we're modifying the matrix directly.
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.
If it's only used here, that's fine, but I think it might be better to prepare it as a variable in advance because it will be used later when creating a method for moving with the right mouse button.
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.
ah, were you thinking of implementing that via the projection matrix? I was thinking movement would still be done by changing uModelViewMatrix
(at least for perspective cameras), would that also work for ortho cameras?
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.
That idea is to drop the gaze point into the normalized device coordinate system using the camera matrix and the projection matrix, move the mouse by the inverse of the movement distance, and focus on the position where the normalized device coordinates come to the destination.
It shifts the viewpoint by parallel movement.
This allows the movement of the camera along with the movement of the mouse. I don't use the modelview matrix because it doesn't involve model transformations. I've already confirmed that it works fine with perspective, ortho, and frustum.
demo:improve panning
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.
Ahh I see, I thought you meant you would be updating the projection matrix to implement movement, I see what you mean now -- this is what I was suggesting 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.
I think it might still be more readable if we declare uP
just in that branch for that case, as we're just reading it. Then, here, where we're actually modifying it, it's clear to readers that the uPMatrix
property will be modified.
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 got it. So, let's write this directly and declare it again in the method I will implement later.
The default value of frustum() has changed, so I rewrote the reference.
Added the reason why the projection matrix is changed if it is an orthogonal projection when scrolling the mouse in orbitControl().
In order to clearly indicate that the elements of the matrix have changed, I decided to write them directly instead of using variables.
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 for making this change, I think this makes these camera modes a lot nicer to work with!
Thanks for advices! |
Resolves #6106
Changes:
First, Causes the camera properties cameraNear and cameraFar to be set to the near and far values when calling ortho() and frustum(). These values are used as limits when changing the scale in orbitControl().
Second, I fixed frustum() default value like ortho(). The previous default value ignored how to set the value of frustum(), so if you applied it as it was, the object would disappear.
Also changed the diagonal y to -y in the frustum() projection matrix. This is not so much a fix as perspective() and ortho() are like that, so I wanted to match them.
Finally, in the case of ortho() in orbitControl(), it was not possible to change the scale by scrolling the mouse, but by changing the projection matrix, it became possible.
Screenshots of the change:
sample code: fix_ortho_frustum Demo
This is a video showing how the scale can be changed even when using orbitControl() with ortho().
2023-04-21.00-37-25.mp4
PR Checklist
npm run lint
passes