title: Flip (mirror) any object with Three.js
body: <h1>Update 2019</h1>
  <p>Since <a href="https://github.com/mrdoob/three.js/releases/tag/r89" rel="noreferrer">r89</a> three.js will also adjust the faces and normals. To flip/mirror an object simply use:</p>
  <pre><code>object3D.applyMatrix(new THREE.Matrix4().makeScale(-1, 1, 1));
  </code></pre>
  <p>No other adjustments as shown in the original solution are required. Link to the ticket: <a href="https://github.com/mrdoob/three.js/pull/12787" rel="noreferrer">Support reflection matrices. #12787</a></p>
  <h1>Original question</h1>
  <p>I'm trying to create an utility that would flip any object in Three.js scene. The flipping itself is the easy bit:</p>
  <pre><code>object3D.applyMatrix(new THREE.Matrix4().makeScale(-1, 1, 1));
  </code></pre>
  <p>What is proving difficult is fixing faces and normals after the flip. The result looks quite messed up. Images of the source and flipped object: <a href="https://dl.dropboxusercontent.com/u/20925853/Flipped.png" rel="noreferrer">https://dl.dropboxusercontent.com/u/20925853/Flipped.png</a></p>
  <p>I have seen a number of threads where this and similar issues were discussed but did not find anything usable. Does anybody know what I'm missing there? - Thanks!</p>
  <p>Sample code on Js fiddle:
  <a href="https://jsfiddle.net/7dwh084w/" rel="noreferrer">https://jsfiddle.net/7dwh084w/</a></p>
  <pre><code>var renderer;
  var scene;
  var camera;
  
  function render() {
  
      renderer.render(scene, camera);
  };
  
  function load(callback) {
  
      new THREE.ColladaLoader().load(&quot;https://dl.dropboxusercontent.com/u/20925853/Kitchen.dae&quot;, function (result) {
  
          var mesh = result.scene.children[0].children[0].clone();
          if (callback) callback(mesh);
      });
  }
  
  function init() {
  
      scene = new THREE.Scene();
      camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 10000);
      camera.position.z = 1000;
  
      var light = new THREE.DirectionalLight(0xffffff);
      light.position.set(2, 1, 1).normalize();
      scene.add(light);
      var ambient = new THREE.AmbientLight(0x777777);
      scene.add(ambient);
  
      var controls = new THREE.OrbitControls(camera);
      controls.damping = 0.2;
      controls.addEventListener('change', render);
  
      renderer = new THREE.WebGLRenderer();
      renderer.setSize(window.innerWidth, window.innerHeight);
      document.body.appendChild(renderer.domElement);
  
      load(function (mesh) {
  
          flipMesh(mesh);
  
          scene.add(mesh);
          render();
      });
  
      render();
  }
  
  function flipMesh(object3D) {
  
      object3D.applyMatrix(new THREE.Matrix4().makeScale(-1, 1, 1));
      reverseWindingOrder(object3D);
  }
  
  function reverseWindingOrder(object3D) {
  
      // TODO: Something is missing, the objects are flipped alright but the light reflection on them is somehow broken
  
      if (object3D.type === &quot;Mesh&quot;) {
  
          var geometry = object3D.geometry;
  
          for (var i = 0, l = geometry.faces.length; i &lt; l; i++) {
  
              var face = geometry.faces[i];
              var temp = face.a;
              face.a = face.c;
              face.c = temp;
  
          }
  
          var faceVertexUvs = geometry.faceVertexUvs[0];
          for (i = 0, l = faceVertexUvs.length; i &lt; l; i++) {
  
              var vector2 = faceVertexUvs[i][0];
              faceVertexUvs[i][0] = faceVertexUvs[i][2];
              faceVertexUvs[i][2] = vector2;
          }
  
          geometry.computeFaceNormals();
          geometry.computeVertexNormals();
      }
  
      if (object3D.children) {
  
          for (var j = 0, jl = object3D.children.length; j &lt; jl; j++) {
  
              reverseWindingOrder(object3D.children[j]);
          }
      }
  }
  
  init();
  </code></pre>