0

I am using TransformControls package (found here: https://github.com/lucascassiano/three-transform-controls). The transform controls seem to function more or less fine, but it causes two major problems in my app:

1) it doesn't change the mode to rotation/scaling/etc. It gives the following error, when called: "Uncaught TypeError: Cannot read property 'setMode' of undefined".

2) on my screen it shows a really weird haywire of red lines, alongside with the gizmos (please, see the attached screenshot). both of the problems on one picture

It seems that the problem lies somewhere in the scope of the variables, but I cannot find it.

export default {
name: 'ThreeTest',
data() {
  return {
    mouse: new THREE.Vector2(),
    rayCaster: new THREE.Raycaster(),
    spheres: [],
    objects: [],
    intersectsPoi: null,
    transformControls: null
  };
},
methods: {
  init() {

    this.transformControls = new TransformControls(this.camera, this.renderer.domElement );


    // EVENT LISTENERS:
    map.addEventListener('mousedown', this.transformPoi, false);

    this.transformControls.addEventListener( 'change', this.render );
    this.transformControls.addEventListener( 'dragging-changed', function ( event ) {
      this.controls.enabled = ! event.value;
    } );

    window.addEventListener( 'keydown', function ( event ) {
      switch ( event.keyCode ) {
        case 81: // Q
          this.transformControls.setSpace( this.transformControls.space === "local" ? "world" : "local" );
          break;
        case 17: // Ctrl
          this.transformControls.setTranslationSnap( 100 );
          this.transformControls.setRotationSnap( THREE.Math.degToRad( 15 ) );
          break;
        case 87: // W
          this.transformControls.setMode( "translate" );
          break;
        case 69: // E
          this.transformControls.setMode( "rotate" );
          break;
        case 82: // R
          this.transformControls.setMode( "scale" );
          break;
        case 187:
        case 107: // +, =, num+
          this.transformControls.setSize( this.transformControls.size + 0.1 );
          break;
        case 189:
        case 109: // -, _, num-
          this.transformControls.setSize( Math.max( this.transformControls.size - 0.1, 0.1 ) );
          break;
        case 88: // X
          this.transformControls.showX = ! this.transformControls.showX;
          break;
        case 89: // Y
          this.transformControls.showY = ! this.transformControls.showY;
          break;
        case 90: // Z
          this.transformControls.showZ = ! this.transformControls.showZ;
          break;
        case 32: // Spacebar
          this.transformControls.enabled = ! this.transformControls.enabled;
          break;
      }
    } );

  },

  // HELPER FUNCTIONS:

  mouseOverScene (event) {
    event.preventDefault();
    let rect = event.target.getBoundingClientRect();
    let x = event.clientX - rect.left;
    let y = event.clientY - rect.top;

    this.mouse.x = ( x / this.mapWidth) * 2 - 1;
    this.mouse.y = - ( y / this.mapHeight ) * 2 + 1;

    this.rayCaster.setFromCamera(this.mouse, this.camera);
  },


  transformPoi (event) {
    console.log('I am in');
    if (event) {
      this.mouseOverScene(event);
    };

    let intersectsPoi = this.intersectsPoi;
    intersectsPoi = this.rayCaster.intersectObjects(this.spheres);
    console.log(intersectsPoi);
    let selected;

    if (intersectsPoi.length > 0 ) {
      selected = intersectsPoi[0].object;
      console.log(`The intersected is ${selected}`);
      this.transformControls.attach( selected );
      this.scene.add(this.transformControls);
    } else {
      this.transformControls.detach( selected );
      this.scene.remove(this.transformControls);
    };
  },

}

EXPECTED RESULT: so it should change the modes of the transformControls with the press of the associated keys.

ACTUAL RESULT: well, it doesn't do it :(

RaulS
  • 99
  • 8

1 Answers1

1

I guess the problem with this ("Uncaught TypeError: Cannot read property 'setMode' of undefined".):

 window.addEventListener( 'keydown', function ( event ) {

   // here this might be not what you want.
   // this refers to window,
   // but window doesn't have transformControls
   console.log(this)
 });

arrow function allows this be inherited from its parent function. In that case, this will refer to the object with transformControls property:

window.addEventListener( 'keydown', event => {

});
Vadi
  • 2,446
  • 2
  • 8
  • 26
  • It works! Thanks! Can you probably explain why the problem occured in the first place though? Also, do you probably have an idea what's up with all the haywire on the screenshot? It only appears at the 'translate' mode. – RaulS Jan 28 '19 at 16:01
  • 1
    @RaulS, see https://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work – gman Jan 28 '19 at 16:27