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

Raycaster.prototype.setFromCamera() support for cameras with matrix-defined position #6230

Closed
wants to merge 1 commit into from

Conversation

Densaugeo
Copy link
Contributor

Raycaster.prototype.setFromCamera() was getting the camera's position from camera.position, which isn't updated on cameras that are moved around by direct matrix transform.

I believe grabbing it the position from camera.matrix still gives an accurate position for cameras that use the position property. At least, the canvas_interactive_cubes example still works.

@mrdoob
Copy link
Owner

mrdoob commented Mar 12, 2015

Hmmm... The matrix may have not be updated at that point :/

@WestLangley
Copy link
Collaborator

camera.position, which isn't updated on cameras that are moved around by direct matrix transform.

Are you setting camera.matrixAutoUpdate = false?

@Densaugeo
Copy link
Contributor Author

Are you setting camera.matrixAutoUpdate = false?

Yes, in which case camera.position doesn't necessarily reflect the camera's position. If camera.matrix is what the renderer uses, then the position extracted from camera.matrix will always be accurate.

@WestLangley
Copy link
Collaborator

Are you setting camera.matrixAutoUpdate = false?

Yes

Object3D.matrixAutoUpdate = false is only to be used to prevent the renderer from recomputing the object matrix every frame when the object is known to be static . It should not be used as an alternative method of setting the object transform by manipulating the object matrix directly.

If we were to support changing the matrix directly, then every method that relies on rotation information must have two logic paths -- one to get it from the matrix, and one to get it from the rotation vector or quaternion.

If an object is not static, the user must manipulate the object by changing its position, rotation, and scale vectors, and not by changing the object's matrix directly.

That being said, I think this method can be improved -- but not for your reason.

I'll think about the implications of the following change, instead:

this.ray.origin.setFromMatrixPosition( camera.matrixWorld ); // use world matrix

In the mean time, I suggest you change your methodology to avoid potential pitfalls.

@mrdoob
Copy link
Owner

mrdoob commented Mar 13, 2015

Object3D.matrixAutoUpdate = false is only to be used to prevent the renderer from recomputing the object matrix every frame when the object is known to be static . It should not be used as an alternative method of setting the object transform by manipulating the object matrix directly.

Yeah. I mean, you can update matrix directly. But understand that you're a bit on your own. If we could use Object.observe() we could update matrix when the user updates position automatically and your code suggestion would work. But right now we're a bit limited...

I'll think about the implications of the following change, instead:

this.ray.origin.setFromMatrixPosition( camera.matrixWorld ); // use world matrix

It's the same issue. By the time the user is calling that method we can't guarantee that camera.matrixWorld is up to date.

@WestLangley
Copy link
Collaborator

It's the same issue. By the time the user is calling that method we can't guarantee that camera.matrixWorld is up to date.

This has always been a problem in three.js.

Note that in this case, Raycaster.setFromCamera() calls Vector3.unproject(), which accesses camera.matrixWorld anyway.

In (many) other methods such as object3D.getWorldPosition(), we force a call to updateMatrixWorld() -- but that is not even correct, because we should update the world matrix of all the object's parents to ensure the world matrix is properly updated.

@Densaugeo
Copy link
Contributor Author

For the use of Raycaster.prototype.setFromCamera() in the clickable objects demo, the important part would seem to be reading the scene as the renderer draws it, since that is how users click on things.

My understanding is that when Object3D.matrixAutoUpdate = true, .matrix is updated from .position etc. on every render. When Object3D.matrixAutoUpdate = false, the renderer draws the object based on .matrix without checking .position. So, in either case, .matrix gives the position where the renderer will draw. .position may sometimes give a different position, but in that case an object will still be drawn based on .matrix, which is the important thing (at least in the case of making objects clickable).

Are there other uses for Raycaster.prototype.setFromCamera() where the ray needs to be set based on a recently updated .position, instead of being set as the renderer sees the camera (from .matrix)?

@mrdoob
Copy link
Owner

mrdoob commented Mar 14, 2015

Oh. Sorry... I forgot that this is done per frame...

Still, what can happen is that matrix can be one frame behind because matrix (and matrixWorld) gets updated when calling renderer.render(). If the user only modifies position then that's likely to be up to date. But yes, stuff breaks if the camera is in a hierarchy...

@luyaor
Copy link

luyaor commented Jul 15, 2018

Dear Densaugeo & mrdoob & WestLangley,

We are working on identifying redundant development and duplicated pull requests. We have found there is a pull request: #6301 which might be duplicated to this one and already merged into main stream. So maybe this pull request should be closed.

We would really appreciate if you could help us to validate and give us some feedback.
Thank you very much for your time!

Sincerely,
Luyao

@WestLangley
Copy link
Collaborator

Closing. This feature was duplicated and merged in #6301.

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

Successfully merging this pull request may close these issues.

4 participants