How to prevent shrinking TransformControls?

When TransformControls is behind the object you want it to stay the same size no matter if the user zoom in or out. At the moment when I zoom in or out the size changes from small to enormous. The camera is a PerspectiveCamera. Not sure if it is the camera’s problem or the scaling but I have attempted on keeping it the same size:

// Calculate the scale based on the object's size and the camera's distance
  const objectSize = bounds.getSize(new THREE.Vector3());
//   const objectDistance = camera.position.distanceTo(theeBox.position);
//   const scale = objectSize.length() / objectDistance;
//   console.log(objectSize)

  transformControls.scale.set(objectSize.x - 3.6, objectSize.y - 3.6, objectSize.z - 3.6);

Note: I added the -3.6 because I also liked the Controls to be a bit away from the object.

But that doesn’t affect the scaling much as I have this:

or this:

How can TransformControls stay at object size?

MRC

import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js';

const boxGeometry = new THREE.BoxGeometry(5, 5, 5);

// Load wood texture using the provided URL
const woodTexture = new THREE.TextureLoader().load('https://cdn.glitch.global/364206c7-9713-48db-9215-72a591a6a9bd/pexels-fwstudio-129733%20(1).jpg?v=1658926492448');

const theeBoxMaterial = new THREE.MeshBasicMaterial({ map: woodTexture });
const theeBox = new THREE.Mesh(boxGeometry, theeBoxMaterial);
const renderer = new THREE.WebGLRenderer();
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
  45,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);

const gridHelper = new THREE.GridHelper(30);
scene.add(gridHelper);

// Adjust the initial position of the cube to be above the grid helper
theeBox.position.set(0, 2.6, 0);
scene.add(theeBox);

const orbitControls = new OrbitControls(camera, renderer.domElement);
const transformControls = new TransformControls(camera, renderer.domElement);
transformControls.traverse(e => {
  if (e.material) {
    e.material.depthTest = true;
  }
});

let transformAnchor = new THREE.Object3D();
scene.add(transformAnchor);
let bounds = new THREE.Box3().setFromObject(theeBox);
transformAnchor.position.copy(bounds.min);
transformAnchor.attach(theeBox);

transformControls.attach(transformAnchor);
transformControls.setMode('translate');
const gizmo = transformControls._gizmo.gizmo;
[83, 86, 89, 91, 92, 93, 94].forEach(axis => {
  const obj = gizmo.translate.getObjectById(axis);
  obj.visible = false;
  obj.layers.disable(0);
});

scene.add(transformControls);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

camera.position.set(50, 30, 20);
camera.lookAt(0, 0, 0);

let isDragging = false;

// TODO: Make the cube to be above the grid helper by default
// TODO: Prevent the arrows from shrinking when zooming
// TODO: Add degree rotating arrows

transformControls.addEventListener('dragging-changed', function (event) {
  orbitControls.enabled = !event.value;
  isDragging = event.value;
});

function animateTheeBox() {
  if (!isDragging && !orbitControls.enabled) {
    rayCasters.setFromCamera(mousePos, camera);
    const intersect = rayCasters.intersectObjects([theeBox]);

    if (intersect.length === 0) {
      const moveSpeed = 0.1;
      camera.position.x += (mousePos.x - 0.5) * moveSpeed;
      camera.position.y += (mousePos.y - 0.5) * moveSpeed;
      camera.lookAt(0, 0, 0);
    }
  }

  // Calculate the scale based on the object's size and the camera's distance
//   const objectSize = bounds.getSize(new THREE.Vector3());
//   const objectDistance = camera.position.distanceTo(theeBox.position);
//   const scale = objectSize.length() - objectDistance;
//   console.log(objectSize)

//   transformControls.scale.set(objectSize.x - 3.6, objectSize.y - 3.6, objectSize.z - 3.6);

  renderer.render(scene, camera);
}

renderer.setAnimationLoop(animateTheeBox);

Note: I commented my attempt because it was not working…

Is this a bit closer to what you need? The magic is in line 61.

image

https://codepen.io/boytchev/full/MWxOWga

3 Likes

It’s not close bro. It’s PERFECT! Although I don’t know why they appear very small at me but I think I need to mess a bit with scaling.

Edit: Fixed!!!