What should I do if I assign an anchor/pivot point to an object, and the TransformControls are not updated synchronously?


three.ez - TransformControls (forked) - StackBlitz

transform Controls center not align pivot

The transformControls was not developed to support a pivot point.

You should create your own modified control based on the original transformControls.

Globally overriding.updateMatrix like that seems like a potential source of hard to find/fix bugs?

If you need to pivot around a different origin, just add a Group or Object3D above the object:

So instead of:

scene->[
mesh
]

scene->[
pivot->[
mesh
]
]

You can use .attach instead of .add to make this setup easier.

What your override code is doing is like a less useful version of ^, that may break compatibility, and adds extra code (the check for .pivot) to every single object in the scene * every render…
So in a scene with 10000 objects, you’re adding 10000 null checks every time render is called.
Additionally it will break other library internals that may rely on overriding those methods themselves… It may break shaders that do that matrix updating themselves… It may break post processing effects that have to manipulate or examine objects. It may also break the existing implementation .updateMatrix that may have to be changed in the future by the threejs folks.
The whole point of a scene graph is to encapsulate such nested transforms.

Here’s how I would do it if I needed the controls to pivot differently… it’s less code and doesn’t need to modify the library or muck with matrices etc: (Search for THRAX to see what I changed… )

This way the scene stays compatible when exporting or working within other supporting tools.

1 Like

I’ve tried to do this, but it’s not easy to use, I have multiple scenes, a scene rendering helper, a scene rendering object, using attah makes my scene tree and hierarchy messy, etc

1 Like

… … … ok :slight_smile:

1 Like

@manthrax I think your solution is the best

Do you think it’s okay to implement it this way so that you don’t have any problems related to hierarchy?

function attachTransformControls(target: Mesh): void {
  const originalParent = pivotHelper.parent;

  // remove the pivotHelper from the old target
  if (originalParent) {
    const oldTarget = pivotHelper.children[0];
    originalParent.attach(oldTarget);
    pivotHelper.removeFromParent();
  }

  // add pivotHelper as parent of the new target
  if (target.pivot) {
    const targetPosition = target.getWorldPosition(_v);
    pivotHelper.position.addVectors(targetPosition, target.pivot);
    
    target.parent.attach(pivotHelper);
    pivotHelper.attach(target);
    control.attach(pivotHelper);
  } else {
    control.attach(target); 
  }
}
1 Like

Maybe you add these few lines of code, switch between use, scale, rotate, and pan to manipulate the model multiple times, and you will find a lot of bugs


document.addEventListener(‘keydown’, () => {
if (control.mode == ‘translate’) {
control.mode = ‘rotate’;
} else if (control.mode == ‘rotate’) {
control.mode = ‘scale’;
} else {
control.mode = ‘translate’;
}
});

@agargaro You can’t find it by using panning, rotating, and zooming alone, so you can use it in combination

Have you looked at :
https://threejs.org/docs/#examples/en/controls/TransformControls.setSpace

You may need to set to controls.setSpace(‘local’) ?

I corrected some things in the example, however, the attach method has this limitation (from doc):

Note: This method does not support scene graphs having non-uniformly-scaled nodes(s).

So if you scale the objects uniformly, this should work.


After dragging the rotation zoom several times, the deviation from the actual pivot position is very large

And there will also be jumping problems