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

Object3D: Introduce .forward property #14703

Closed
wants to merge 6 commits into from
Closed

Conversation

Mugen87
Copy link
Collaborator

@Mugen87 Mugen87 commented Aug 13, 2018

I'd like to suggest a new property Object3D.forward which defines the forward direction in the local space of the object. Using such a property makes it much nicer to implement Object3D.getWorldDirection() since it's not necessary anymore to override the method in classes like Camera. It's sufficient to change the forward property to e.g. ( 0, 0, - 1 ) in the ctor.

This PR would undo #14677 but I personally would choose a more flexible and clean approach than the current version in dev. The interesting thing is that the introduction of the local forward vector could be the basis for an alternative implementation of Object3D.lookAt() which does not need to know it's type of object anymore. So statements like this.isCamera would be not necessary.

@Mugen87
Copy link
Collaborator Author

Mugen87 commented Aug 13, 2018

The interesting thing is that the introduction of the local forward vector could be the basis for an alternative implementation of Object3D.lookAt() which does not need to know it's type of object anymore.

I've added the code so you can see the approach. The idea is to add Matrix3.lookAt() with a new signature that is now used in Object3D.lookAt().

Code is mainly based on:

https://github.com/juj/MathGeoLib/blob/master/src/Math/float3x3.h#L147-L178
https://github.com/juj/MathGeoLib/blob/master/src/Math/float3x3.cpp#L616-L677

@mrdoob
Copy link
Owner

mrdoob commented Aug 13, 2018

Interesting! This would also allow people to change the what's the forward direction of the camera 👌

What do you think @WestLangley?

@mrdoob mrdoob added this to the r96 milestone Aug 13, 2018
@Mugen87
Copy link
Collaborator Author

Mugen87 commented Aug 13, 2018

I also like the idea that lookAt() belongs to Matrix3. If you think of a pure rotation matrix, you normally have a 3x3 matrix in mind. If this gets merged, Matrix4.lookAt() can go into Three.Legacy.js.


var localRight = new Vector3();
var worldRight = new Vector3();
var worldUp = new Vector3( 0, 1, 0 );
Copy link
Contributor

Choose a reason for hiding this comment

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

This is fixing world up to be +y ?
What impact would this have for using +z as up?

Copy link
Collaborator Author

@Mugen87 Mugen87 Aug 13, 2018

Choose a reason for hiding this comment

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

This is fixing world up to be +y ?

worldUp could be actually configurable. I've hard-wired this to always assumes Y-Up as global up direction of the scene in world space.

Copy link
Contributor

Choose a reason for hiding this comment

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

some awkward people (ie me*) work with up = +z, the existing Matrix4.lookAt() has an
exception around for the z up case #11543 already.

  • geographic models fit better.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If we find a way to make it configurable, it should be no problem. Do you have any ideas?

Copy link
Collaborator Author

@Mugen87 Mugen87 Aug 13, 2018

Choose a reason for hiding this comment

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

Damn. I realize right now that this PR breaks all user code where camera.up.set( 0, 0, 1 ) is already set. https://threejs.org/examples/webgl_loader_pcd.html is such a problematic case. You would now have to change worldUp instead. Even if we apply a configuration option, the approach is not a backward-compatible. Too bad, it seems we can't go this way 😞 .

Copy link
Owner

Choose a reason for hiding this comment

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

Do you mean that these use cases will break unless the user also does camera.forward.set( 0, -1, 0 )?

Copy link
Collaborator Author

@Mugen87 Mugen87 Aug 13, 2018

Choose a reason for hiding this comment

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

I don't know why yet but this does not solve the issue. It works if you remove camera.up.set( 0, 0, 1 ) and set worldUp to (0, 0, 1) (e.g. something like THREE.WorldUp.set( 0, 0, 1)). Even then, for some reasons TransformControls seems to have problems with this approach (it internally uses Matrix4.lookAt()).

Copy link
Collaborator Author

@Mugen87 Mugen87 Aug 14, 2018

Choose a reason for hiding this comment

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

After a closer look, the main problem is caused since the new Matrix3.lookAt() interprets Object3D.up differently than Matrix4.lookAt(). That's the reason why both methods do not work together like in the example. From my point of view, Matrix3.lookAt() is the better approach since it's a more clear implementation of what's actually happening in lookAt(): A given Object3D.up vector is mapped like all other local basis vectors (forward, right) to the counterpart of a world coordinate frame (defined by worldUp, targetDirection, and worldRight). This is the way .lookAt() should work and Matrix3.lookAt() is exactly implemented like that.

Even if we introduce THREE.WorldUp to allow a configuration (e.g. to enable Z-UP) and then use this value in Matrix3.lookAt(), we would have to migrate all code that uses Matrix4.lookAt() to Matrix3.lookAt(). Besides, setting camera.up.set( 0, 0, 1 ) is not necessary anymore.

So introducing this new approach is a breaking change. If there will ever be a three.js 2, this should be the way to go^^.

Copy link
Owner

Choose a reason for hiding this comment

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

Thanks for investigating!

@Mugen87
Copy link
Collaborator Author

Mugen87 commented Aug 13, 2018

48c15a1 is necessary since up and forward are not allowed to be collinear.

@Mugen87
Copy link
Collaborator Author

Mugen87 commented Aug 13, 2018

Closing, see #14703 (comment)

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.

3 participants