-
-
Notifications
You must be signed in to change notification settings - Fork 35.9k
TransformControls: introduce scaleFromEdge property #31346
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
Conversation
Remove unused import.
Fix formatting.
The feature is actually quite nice! I've tested it in |
One edge case which I've since discovered: it fails if you scale the object through its origin. Since negative scales also have other ugly side effects (translation in |
Revert `else` branch.
What do you mean with failing? Isn't the scale behavior equal to the default behavior (meaning when |
I mean that, with negative scales, pulling from an edge will actually use the pulled edge itself as an anchor, instead of the opposite edge. |
When the scaling gets negative, the gizmo might be flipped which looks odd, imo. Instead of adding a flag, it's probably best to disallow negative scaling in AFAICS, the scale gizmo in Blender does not allow negative scaling as well. If wanted, you must configure the negative scale over the UI. |
I've added a suggested way of handling this (just ignore scale movements which would make the scale negative) |
Any chance you could add a video of the feature in the first post? |
Here is a live example with a custom version of
|
I've just tried in blender and the widget does allow for negative scaling (note the Y-value in the UI). I don't recall a 3D DCC that disallowed negative scaling via drag: blender-scale.mov
Vector direction reversing is a mathetmatical consequence of a negative scale. Users can choose to disallow negative scaling (via value clamping, for example) if needed for their projects but it's otherwise explicitly supported in three.js (winding direction is flipped when rendering, etc) and not something that should be considered inherently "ugly". If other projects like three-csg do not support negative scaling then an issue can be submitted at that project (there's no reason it can't be supported) but it's not a reason to broadly restrict what is typical 3d editor behavior. |
Good catch! I've used the In this case, we should allow negative scale in |
Any objections to making [1] a configurable opt-in option? [1] da4bf71 |
Is there any reason this can't already be done? It's trivial to clamp the scale of the object. control.addEventListener( 'change', e => {
e.target.object.scale.max( new THREE.Vector3( 0, 0, 0 ) );
} ); |
If you have |
This is true of any scale clamping, not just when clamping at zero. Even if a flag is added for disabling negative scaling this issue of the object drifting as you scale it by the edge if the user needs to clamp to a positive scale still occurs. Perhaps negative scaling is the only thing that needs to be prevented in some cases but it's not a generally robust solution. In my opinion it's best to keep this feature separate from TransformControls. It can already be implemented using the existing events which provides the flexibility for users to provide any restrictions they need on the transform. Here's a demonstration showing scale clamping at a small epsilon (TransformControls seems to break with 0 scale) and at 2: https://jsfiddle.net/L12ecmpw/ scaling.mov |
Since users can implement this kind of custom scaling in an @manisandro Thanks for your effort here. Even the PR isn't merged, it is now a informative discussion for developers who looking for a custom scaling solution. Here is the custom event listener just for the case jsfiddle goes offline in the future: control.addEventListener( 'objectChange', e => {
const control = e.target;
const { axis, mode, object } = control;
if ( mode == 'scale' ) {
const lowerCaseAxis = axis.toLowerCase();
object.scale[ lowerCaseAxis ] = THREE.MathUtils.clamp( object.scale[ lowerCaseAxis ], 1e-4, 2 );
// construct the new box
const newBox = new THREE.Box3();
newBox.copy( mesh.geometry.boundingBox );
newBox.min.multiply( object.scale );
newBox.max.multiply( object.scale );
// determine which side the clamp to
const negativeScaling = control.pointStart[ lowerCaseAxis ] < 0 ? - 1 : 1;
// find the change in the box size
const width = box.max[ lowerCaseAxis ] - box.min[ lowerCaseAxis ];
const newWidth = newBox.max[ lowerCaseAxis ] - newBox.min[ lowerCaseAxis ];
const scaleDiff = newWidth / width;
// offset the size
object.position.copy( center );
object.position[ lowerCaseAxis ] += negativeScaling * ( width * scaleDiff - width ) * 0.5;
}
} ); |
This PR proposes an option to the TransformControls to scale objects while keeping the opposite edge as the fixed anchor point, instead of scaling around the center. It currently only works for simple objects, not object groups.