leonnicklas
leonnicklas

Reputation: 453

"control.setRotationSnap" functionality in TransformControls.js (Three.js) not working

I am trying to get the "control.setRotationSnap" functionality from the "TransformControls.js" script working, but unfortunately it doesn't.

doing my resaerch I just found somebody writing the code may be not fully included yet... (https://discourse.threejs.org/t/transform-controls-rotation-snapping/8632)

My current code where I'm trying to use the feature:

let renderer, scene, camera, light1, light2, light3, orbit, control, texture, material, loader, mesh;

let renderer = new THREE.WebGLRenderer();
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 3000);
let light1 = new THREE.DirectionalLight(0xfffffe, 2);
let light2 = new THREE.DirectionalLight(0xfffeff, 1.75);
let light3 = new THREE.DirectionalLight(0xfeffff, 0.75);
let orbit = new THREE.OrbitControls(camera, renderer.domElement);
let control = new THREE.TransformControls(camera, renderer.domElement);
let material = new THREE.MeshPhongMaterial({ color: 0x888888, specular: 0x111111, shininess: 2 });
let loader = new THREE.STLLoader();

// renderer
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// scene
scene.add(new THREE.GridHelper(500, 50));

// camera
camera.position.set(0, 25, 100);
camera.lookAt(0, 0, 0);

// light
light1.position.y = +10;
light1.position.x = +10;
light1.position.z = +10;
light2.position.y = 0;
light2.position.x = -10;
light2.position.z = -10;
light3.position.y = -10;
light3.position.x = 0;
light3.position.z = 0;
scene.add(light1);
scene.add(light2);
scene.add(light3);

// orbit
orbit.update();
orbit.addEventListener('change', render);

// control
control.addEventListener('change', render);
control.addEventListener('dragging-changed', function (event) {
    orbit.enabled = !event.value;
});

// loader
loader.load('./stl/1.stl', function (geometry) {

    // mesh
    mesh = new THREE.Mesh(geometry, material);
    mesh.position.set(0, 0, 0);
    scene.add(mesh);

    // control
    control.attach(mesh);
    scene.add(control);

    render();
});

// window resize
window.addEventListener('resize', onWindowResize, false);
// key controls
window.addEventListener('keydown', function (event) {
    switch (event.keyCode) {
        case 81: // Q
            control.setSpace(control.space === "local" ? "world" : "local");
            break;
        case 17: // Ctrl
            control.setTranslationSnap(10);
// ************************* THIS LINE BETWEEN ISN'T WORKING AT ALL *************************
            control.setRotationSnap(Math.degToRad(90));
// ************************* THIS LINE BETWEEN ISN'T WORKING AT ALL *************************
            break;
        case 87: // W
            control.setMode("translate");
            break;
        case 69: // E
            control.setMode("rotate");
            break;
        case 82: // R
            control.setMode("scale");
            break;
        case 187:
        case 107: // +, =, num+
            control.setSize(control.size + 0.1);
            break;
        case 189:
        case 109: // -, _, num-
            control.setSize(Math.max(control.size - 0.1, 0.1));
            break;
        case 88: // X
            control.showX = !control.showX;
            break;
        case 89: // Y
            control.showY = !control.showY;
            break;
        case 90: // Z
            control.showZ = !control.showZ;
            break;
        case 32: // Spacebar
            control.enabled = !control.enabled;
            break;
    }
});
// key controls (2)
window.addEventListener('keyup', function (event) {
    switch (event.keyCode) {
        case 17: // Ctrl
            control.setTranslationSnap(null);
            control.setRotationSnap(null);
            break;
    }
});
render();


// FUNCTION window resize
function onWindowResize() {
    renderer.setSize(window.innerWidth, window.innerHeight);
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();

    render();
}
// FUNCTION render
function render() {
    renderer.render(scene, camera);
}

These are the lines of code in the TransformControls.js script where the rotation snap functionality is implemented:

// Apply rotation snap

if ( this.rotationSnap ) rotationAngle = Math.round( rotationAngle / this.rotationSnap ) * this.rotationSnap;

    this.rotationAngle = rotationAngle;

That's all there is...

What I want to achieve: The "control.setRotationSnap" should let the 3D-Object (STL) snap in 90 degree steps...

If I try to use it, it just won't work at all.

Maybe someone had the same issue?

Best regards, Leon

Upvotes: 1

Views: 1354

Answers (2)

leonnicklas
leonnicklas

Reputation: 453

Of course the solution was way easier than I thought...

The reason why it wasn't working at all was because the "TransformControls.js" script doesn't include the "Math.degToRad" function - which they used in their example code.

Just paste this small piece of code:

// Converts from degrees to radians.
Math.degToRad = function (degrees) {
    return degrees * Math.PI / 180;
};

into yours and it will work as flawless as possible!

Upvotes: 0

Kim T
Kim T

Reputation: 6444

The original example with snapping is here: https://github.com/mrdoob/three.js/blob/master/examples/misc_controls_transform.html

Looks like you should now use the code:

case 16: // Shift
  control.setTranslationSnap( 100 );
  control.setRotationSnap( THREE.Math.degToRad( 15 ) );
  control.setScaleSnap( 0.25 );
  break;

Upvotes: 1

Related Questions