Three.js: there are multiple problems with TransformControls

Created on 10 Jul 2016  路  23Comments  路  Source: mrdoob/three.js

The effect of scaling is not independent of scene / object dimensions. I had to change these lines to

                        if ( scope.axis === "X" ) scope.object.scale.x = oldScale.x * ( 1 + 0.01 * point.x / oldScale.x );
                        if ( scope.axis === "Y" ) scope.object.scale.y = oldScale.y * ( 1 + 0.01 * point.y / oldScale.y );
                        if ( scope.axis === "Z" ) scope.object.scale.z = oldScale.z * ( 1 + 0.01 * point.z / oldScale.z );

to get sane scaling sensitivity in my project quickly.

Bug

All 23 comments

Here is the fiddle. Try to scale the box, I dare you :)

Oh :shit: there are more problems. 2 out of 3 rotations are broken when the object is edge-on: fiddle. If it's moved even slightly, these rotations behave much better.

God damn it! Just found another issue with translation: you can't move the box using central yellow dot until it is moved around in some other way. And occasionally trying to do so results in the box jumping closer to camera.

On the bright side, next fork of that fiddle will be 1337

Aaaaand, it's mine again - just realized one can scale by middle point in scaling gizmo, and by "can" I mean "can not". Well, you sort of can, but it is also insane magnitude.

And how do you call this?? Setting space to "local" if scaling, means never going back to "world" until the user actually looks into source :S

2 out of 3 rotations are broken when the object is edge-on

this is caused by degenerate case of

var planeIntersect = intersectObjects( pointer, [ _gizmo[ _mode ].activePlane ] );

I could not come up with any kind of clever hack for this - it looks like this needs to be fixed either deep in THREE.Mesh raycasting code, or replace intersectObjects with some sort of analytical intersection for this gizmo.

I tried this stupid hack:

        function hackIntersectionPoint (pointer) {
            var ap = _gizmo[_mode].activePlane, hack = false;
            if (_mode == "rotate") {
                var ax = new THREE.Vector3, ay = new THREE.Vector3, az = new THREE.Vector3;
                ap.matrixWorld.extractBasis (ax, ay, az);
                if (
                    ((ap.name == "YZ") && (ax.y == 0) && (ax.z == 0)) ||
                    ((ap.name == "XZ") && (ay.x == 0) && (ay.z == 0))
                    ) {
                        ap = _gizmo[_mode].planes.XYZE; hack = true;
                    }
            }
            var planeIntersect = intersectObjects( pointer, [ ap ] );
            if (hack) planeIntersect.point.z += 10;
            return planeIntersect;

coded specifically for my setup (camera at 000, mesh at 00negativez) - essentially, intersecting with the plane parallel to the screen - while it sort of works it causes different problems, so not a good way to develop more general hack.

actually, what might work is replacing single planes with two planes at ~1掳 to each other, so there would be an intersection with one of them

@makc the problem is... the central yellow dot is actually the z-facing blue handle looking directly towards the camera. Ideally, the camera-facing handles should be hidden as soon as they are more or less aligned with eye vector. This is because there is no suitable plane to raycast against. So... when X axis is facing camera, only Y and Z should be available and so on.

This issue is fixed in alternate version of TransformControls But as mentioned in #7947 this fix depends on somewhat modular approach to making big and complex scene manipulation tools.

I hope to revisit this project in near future but I don't see the clear path towards contributing fixes back into threejs. I could manually combine all the dependencies into single monolithic TransformControls.js once I get to it.

I think I hit that scope local issue, where everything seems fine, and suddenly the controls align to local scope.

@arodic

I could manually combine all the dependencies into single monolithic TransformControls.js once I get to it.

did you ever get to do it?

I'm currently also having the problem with the TransformControls not doing anything at all when I try to scale in world space.
It seems that the code does not support that. It even forces the space back into local when switching the mode to scale.
Not sure what the reason is for that.

Our issue is that we would like to do transforms on multiple objects. We basically put several objects into a THREE.Group and then do the transform on that group.

In that case the gizmos look weird in local space if the individual objects have been rotated before hand and already have a rotation applied to them. That's why we would like to just do the scaling in world mode, ignoring any rotation and just align the gizmos with the x,y,z axes.
(Does this make sense? 馃槃 )

Shouldn't it be possible to just do same thing when scaling no matter if space is local or world? Or does this have some unintended side effect?

Basically removing line 977:

if ( scope.space === "local" ) {

Maybe I have time next week to look at this.

@arodic I am bumping this with yet another issue. If you omit 2nd argument it subscribes directly to the document, ending up with

TypeError: domElement.getBoundingClientRect is not a function

Not to mention there is no way to change domElement, meaning you cannot create TransformControls before the canvas.

Sorry @makc I haven't done anything with three.js in a long time although I would really love to work on it again.

@sandromartis world space scale is not really possible without another transformation matrix. I would suggest to parent the object you want to scale to an empty Object3D, and scale that instead. If you look at how Maya handles it, scaling in world space doesn't modify object's scale attribute. Instead, it modifies vertex positions in world space. It essentially bakes transformation into geometry and that's not something you cant reset/undo to neutral scale.

Hey @makc you should check out my pull request. A bunch of these issues should be fixed now. If you can help testing, it would be great!

@arodic damn, that was so long ago. I can only suggest you to compare the fiddle I posted with its fork using new version.

oh, there were more than 1 fiddles!

2 out of 3 rotations are broken when the object is edge-on:

this one also seems to be fixed, but it's very hard to lock on one of those circles.

just realized one can scale by middle point in scaling gizmo, and by "can" I mean "can not". Well, you sort of can, but it is also insane magnitude.

this middle point no longer exists.

Setting space to "local" if scaling, means never going back to "world" until the user actually looks into source :S

no fiddle for this, so I have to trust you it's fixed :P

Hmm I'm seeing some weird issues in the fiddle that I didn't see in the editor and TransformControl example. For example, scaling to 0 breaks the controls completely. see here Also rotations are not quite right. I'll need to investigate this.

this middle point no longer exists.

Yeah, I moved the uniform scale handles to the ends so I can have some distance from center to do relative scale from.

no fiddle for this, so I have to trust you it's fixed :P

Yes, the scale mode is still only local space but it wont switch other modes to local.

when there are multiple viewports on one canvas, transformcontrols only is controlled by only the center viewport. I'd like for each of viewport to handle each XYZ plane. As of now is not possible to this is a problem that needs to be fixed.

Was this page helpful?
0 / 5 - 0 ratings