<commit_before>var Mirror = function (opts) {
  this.type = 'mirror';
  this.state = opts.state || Mirror.State.NORMAL;

  opts = opts || {};
  var geometry = new THREE.BoxBufferGeometry( 10, opts.length || 50, 2 );
  var object = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: Math.random() * 0xffffff } ) );
  opts.mouseOverBody = new THREE.Mesh(new THREE.SphereGeometry(opts.length / 2 + 10), new THREE.MeshBasicMaterial({visible: false}));

  this.originalHex = object.material.emissive.getHex();

  GameObject.call(this, object, opts);
};

Mirror.State = {
  NORMAL: 0,
  GHOST: 1,
  HOVERING: 2,
  SELECTED: 3
};

Object.freeze(Mirror.State);

Mirror.prototype = Object.create(GameObject.prototype);

Mirror.prototype.update = function (dt) {
  GameObject.prototype.update.call(this, dt);
  
  if (this.state == Mirror.State.SELECTED) this.body.lookAt(GameInput.getMousePos().clone().add(this.body.position).sub(this.initialPosition));

  let newState;
  switch (this.state) {
    case Mirror.State.NORMAL:
      if (this.isMouseOver && !GameInput.isDown('MOUSE')) {
        newState = Mirror.State.HOVERING;
      }
      break;
    case Mirror.State.SELECTED:
      if (!GameInput.isDown('MOUSE')) {
        newState = this.isMouseOver ? Mirror.State.HOVERING : Mirror.State.NORMAL;
      }
      break;
    case Mirror.State.HOVERING:
      if (!this.isMouseOver) {
        newState = Mirror.State.NORMAL;
      } else if (GameInput.isDown('MOUSE')) {
        newState = Mirror.State.SELECTED;
      }
      break;
  }
  if (newState != null) this.setState(newState);
};

Mirror.prototype.shouldReflectIntersection = function () {
  return this.state != Mirror.State.GHOST;
};

Mirror.prototype.reflectIntersection = function (ray, intersection) {
  // TODO: check if face is front face
  var normal = intersection.face.normal.clone().applyEuler(intersection.object.rotation);
  var newRay = ray.clone();
  newRay.origin.copy(intersection.point);
  newRay.direction.reflect(normal);
  return newRay;
};

Mirror.prototype.hasIntersection = function (gameObjects) {
  // TODO: proper intersection support
  return false;

  var bbox = new THREE.Box3().setFromObject(this.body);
  var hasIntersection = false;
  gameObjects.forEach(function(elem, i) {
    var bboxOther = new THREE.Box3().setFromObject(elem.body);
    hasIntersection = hasIntersection || bbox.intersectsBox(bboxOther);
  });
  return hasIntersection;
};

Mirror.prototype.setState = function (newState) {
  // Update material
  if (newState == Mirror.State.SELECTED || newState == Mirror.State.HOVERING) {
    this.body.material.emissive.setHex( 0xff0000 );
  } else {
    this.body.material.emissive.setHex( this.originalHex );
  }

  // Save initial mouse position
  if (newState == Mirror.State.SELECTED) {
    this.initialPosition = this.body.position.clone();
  }

  this.state = newState;
};<commit_msg>Adjust mirror by dragging left/right or up/down instead<commit_after>var Mirror = function (opts) {
  this.type = 'mirror';
  this.state = opts.state || Mirror.State.NORMAL;

  opts = opts || {};
  var geometry = new THREE.BoxBufferGeometry( 10, opts.length || 50, 2 );
  var object = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: Math.random() * 0xffffff } ) );
  opts.mouseOverBody = new THREE.Mesh(new THREE.SphereGeometry(opts.length / 2 + 10), new THREE.MeshBasicMaterial({visible: false}));

  this.originalHex = object.material.emissive.getHex();

  GameObject.call(this, object, opts);
};

Mirror.State = {
  NORMAL: 0,
  GHOST: 1,
  HOVERING: 2,
  SELECTED: 3
};

Object.freeze(Mirror.State);

Mirror.prototype = Object.create(GameObject.prototype);

Mirror.prototype.update = function (dt) {
  GameObject.prototype.update.call(this, dt);
  
  if (this.state == Mirror.State.SELECTED) this.body.rotation.z = this.initialZAngle + new THREE.Vector2(1, -1).dot(GameInput.getMousePos().clone().sub(this.initialMousePos)) / 30;

  let newState;
  switch (this.state) {
    case Mirror.State.NORMAL:
      if (this.isMouseOver && !GameInput.isDown('MOUSE')) {
        newState = Mirror.State.HOVERING;
      }
      break;
    case Mirror.State.SELECTED:
      if (!GameInput.isDown('MOUSE')) {
        newState = this.isMouseOver ? Mirror.State.HOVERING : Mirror.State.NORMAL;
      }
      break;
    case Mirror.State.HOVERING:
      if (!this.isMouseOver) {
        newState = Mirror.State.NORMAL;
      } else if (GameInput.isDown('MOUSE')) {
        newState = Mirror.State.SELECTED;
      }
      break;
  }
  if (newState != null) this.setState(newState);
};

Mirror.prototype.shouldReflectIntersection = function () {
  return this.state != Mirror.State.GHOST;
};

Mirror.prototype.reflectIntersection = function (ray, intersection) {
  // TODO: check if face is front face
  var normal = intersection.face.normal.clone().applyEuler(intersection.object.rotation);
  var newRay = ray.clone();
  newRay.origin.copy(intersection.point);
  newRay.direction.reflect(normal);
  return newRay;
};

Mirror.prototype.hasIntersection = function (gameObjects) {
  // TODO: proper intersection support
  return false;

  var bbox = new THREE.Box3().setFromObject(this.body);
  var hasIntersection = false;
  gameObjects.forEach(function(elem, i) {
    var bboxOther = new THREE.Box3().setFromObject(elem.body);
    hasIntersection = hasIntersection || bbox.intersectsBox(bboxOther);
  });
  return hasIntersection;
};

Mirror.prototype.setState = function (newState) {
  // Update material
  if (newState == Mirror.State.SELECTED || newState == Mirror.State.HOVERING) {
    this.body.material.emissive.setHex( 0xff0000 );
  } else {
    this.body.material.emissive.setHex( this.originalHex );
  }

  // Save initial mouse position
  if (newState == Mirror.State.SELECTED) {
    this.initialMousePos = GameInput.getMousePos().clone();
    this.initialZAngle = this.body.rotation.z;
  }

  this.state = newState;
};
{'fraction_non_alphanumeric': 0.13866891322662173, 'fraction_numerical': 0.007582139848357203, 'mean_word_length': 3.692490118577075, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '48264', 'n_tokens_mistral': 2010, 'n_tokens_neox': 1907, 'n_words': 374}