(function (global, factory) {
  if (typeof define === "function" && define.amd) {
    define(["exports", "three"], factory);
  } else if (typeof exports !== "undefined") {
    factory(exports, require("three"));
  } else {
    var mod = {
      exports: {}
    };
    factory(mod.exports, global.three);
    global.Geometry = mod.exports;
  }
})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports, _three) {
  "use strict";

  Object.defineProperty(_exports, "__esModule", {
    value: true
  });
  _exports.Geometry = _exports.Face3 = void 0;

  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }

  function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } Object.defineProperty(subClass, "prototype", { value: Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }), writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }

  function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }

  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }

  function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }

  function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }

  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }

  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }

  var _m1 = new _three.Matrix4();

  var _obj = new _three.Object3D();

  var _offset = new _three.Vector3();

  var Geometry = /*#__PURE__*/function (_EventDispatcher) {
    _inherits(Geometry, _EventDispatcher);

    var _super = _createSuper(Geometry);

    function Geometry() {
      var _this;

      _classCallCheck(this, Geometry);

      _this = _super.call(this);
      _this.uuid = _three.MathUtils.generateUUID();
      _this.name = '';
      _this.type = 'Geometry';
      _this.vertices = [];
      _this.colors = [];
      _this.faces = [];
      _this.faceVertexUvs = [[]];
      _this.morphTargets = [];
      _this.morphNormals = [];
      _this.skinWeights = [];
      _this.skinIndices = [];
      _this.lineDistances = [];
      _this.boundingBox = null;
      _this.boundingSphere = null; // update flags

      _this.elementsNeedUpdate = false;
      _this.verticesNeedUpdate = false;
      _this.uvsNeedUpdate = false;
      _this.normalsNeedUpdate = false;
      _this.colorsNeedUpdate = false;
      _this.lineDistancesNeedUpdate = false;
      _this.groupsNeedUpdate = false;
      return _this;
    }

    _createClass(Geometry, [{
      key: "applyMatrix4",
      value: function applyMatrix4(matrix) {
        var normalMatrix = new _three.Matrix3().getNormalMatrix(matrix);

        for (var i = 0, il = this.vertices.length; i < il; i++) {
          var vertex = this.vertices[i];
          vertex.applyMatrix4(matrix);
        }

        for (var _i = 0, _il = this.faces.length; _i < _il; _i++) {
          var face = this.faces[_i];
          face.normal.applyMatrix3(normalMatrix).normalize();

          for (var j = 0, jl = face.vertexNormals.length; j < jl; j++) {
            face.vertexNormals[j].applyMatrix3(normalMatrix).normalize();
          }
        }

        if (this.boundingBox !== null) {
          this.computeBoundingBox();
        }

        if (this.boundingSphere !== null) {
          this.computeBoundingSphere();
        }

        this.verticesNeedUpdate = true;
        this.normalsNeedUpdate = true;
        return this;
      }
    }, {
      key: "rotateX",
      value: function rotateX(angle) {
        // rotate geometry around world x-axis
        _m1.makeRotationX(angle);

        this.applyMatrix4(_m1);
        return this;
      }
    }, {
      key: "rotateY",
      value: function rotateY(angle) {
        // rotate geometry around world y-axis
        _m1.makeRotationY(angle);

        this.applyMatrix4(_m1);
        return this;
      }
    }, {
      key: "rotateZ",
      value: function rotateZ(angle) {
        // rotate geometry around world z-axis
        _m1.makeRotationZ(angle);

        this.applyMatrix4(_m1);
        return this;
      }
    }, {
      key: "translate",
      value: function translate(x, y, z) {
        // translate geometry
        _m1.makeTranslation(x, y, z);

        this.applyMatrix4(_m1);
        return this;
      }
    }, {
      key: "scale",
      value: function scale(x, y, z) {
        // scale geometry
        _m1.makeScale(x, y, z);

        this.applyMatrix4(_m1);
        return this;
      }
    }, {
      key: "lookAt",
      value: function lookAt(vector) {
        _obj.lookAt(vector);

        _obj.updateMatrix();

        this.applyMatrix4(_obj.matrix);
        return this;
      }
    }, {
      key: "fromBufferGeometry",
      value: function fromBufferGeometry(geometry) {
        var scope = this;
        var index = geometry.index !== null ? geometry.index : undefined;
        var attributes = geometry.attributes;

        if (attributes.position === undefined) {
          console.error('THREE.Geometry.fromBufferGeometry(): Position attribute required for conversion.');
          return this;
        }

        var position = attributes.position;
        var normal = attributes.normal;
        var color = attributes.color;
        var uv = attributes.uv;
        var uv2 = attributes.uv2;
        if (uv2 !== undefined) this.faceVertexUvs[1] = [];

        for (var i = 0; i < position.count; i++) {
          scope.vertices.push(new _three.Vector3().fromBufferAttribute(position, i));

          if (color !== undefined) {
            scope.colors.push(new _three.Color().fromBufferAttribute(color, i));
          }
        }

        function addFace(a, b, c, materialIndex) {
          var vertexColors = color === undefined ? [] : [scope.colors[a].clone(), scope.colors[b].clone(), scope.colors[c].clone()];
          var vertexNormals = normal === undefined ? [] : [new _three.Vector3().fromBufferAttribute(normal, a), new _three.Vector3().fromBufferAttribute(normal, b), new _three.Vector3().fromBufferAttribute(normal, c)];
          var face = new Face3(a, b, c, vertexNormals, vertexColors, materialIndex);
          scope.faces.push(face);

          if (uv !== undefined) {
            scope.faceVertexUvs[0].push([new _three.Vector2().fromBufferAttribute(uv, a), new _three.Vector2().fromBufferAttribute(uv, b), new _three.Vector2().fromBufferAttribute(uv, c)]);
          }

          if (uv2 !== undefined) {
            scope.faceVertexUvs[1].push([new _three.Vector2().fromBufferAttribute(uv2, a), new _three.Vector2().fromBufferAttribute(uv2, b), new _three.Vector2().fromBufferAttribute(uv2, c)]);
          }
        }

        var groups = geometry.groups;

        if (groups.length > 0) {
          for (var _i2 = 0; _i2 < groups.length; _i2++) {
            var group = groups[_i2];
            var start = group.start;
            var count = group.count;

            for (var j = start, jl = start + count; j < jl; j += 3) {
              if (index !== undefined) {
                addFace(index.getX(j), index.getX(j + 1), index.getX(j + 2), group.materialIndex);
              } else {
                addFace(j, j + 1, j + 2, group.materialIndex);
              }
            }
          }
        } else {
          if (index !== undefined) {
            for (var _i3 = 0; _i3 < index.count; _i3 += 3) {
              addFace(index.getX(_i3), index.getX(_i3 + 1), index.getX(_i3 + 2));
            }
          } else {
            for (var _i4 = 0; _i4 < position.count; _i4 += 3) {
              addFace(_i4, _i4 + 1, _i4 + 2);
            }
          }
        }

        this.computeFaceNormals();

        if (geometry.boundingBox !== null) {
          this.boundingBox = geometry.boundingBox.clone();
        }

        if (geometry.boundingSphere !== null) {
          this.boundingSphere = geometry.boundingSphere.clone();
        }

        return this;
      }
    }, {
      key: "center",
      value: function center() {
        this.computeBoundingBox();
        this.boundingBox.getCenter(_offset).negate();
        this.translate(_offset.x, _offset.y, _offset.z);
        return this;
      }
    }, {
      key: "normalize",
      value: function normalize() {
        this.computeBoundingSphere();
        var center = this.boundingSphere.center;
        var radius = this.boundingSphere.radius;
        var s = radius === 0 ? 1 : 1.0 / radius;
        var matrix = new _three.Matrix4();
        matrix.set(s, 0, 0, -s * center.x, 0, s, 0, -s * center.y, 0, 0, s, -s * center.z, 0, 0, 0, 1);
        this.applyMatrix4(matrix);
        return this;
      }
    }, {
      key: "computeFaceNormals",
      value: function computeFaceNormals() {
        var cb = new _three.Vector3(),
            ab = new _three.Vector3();

        for (var f = 0, fl = this.faces.length; f < fl; f++) {
          var face = this.faces[f];
          var vA = this.vertices[face.a];
          var vB = this.vertices[face.b];
          var vC = this.vertices[face.c];
          cb.subVectors(vC, vB);
          ab.subVectors(vA, vB);
          cb.cross(ab);
          cb.normalize();
          face.normal.copy(cb);
        }
      }
    }, {
      key: "computeVertexNormals",
      value: function computeVertexNormals() {
        var areaWeighted = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
        var vertices = new Array(this.vertices.length);

        for (var v = 0, vl = this.vertices.length; v < vl; v++) {
          vertices[v] = new _three.Vector3();
        }

        if (areaWeighted) {
          // vertex normals weighted by triangle areas
          // http://www.iquilezles.org/www/articles/normals/normals.htm
          var cb = new _three.Vector3(),
              ab = new _three.Vector3();

          for (var f = 0, fl = this.faces.length; f < fl; f++) {
            var face = this.faces[f];
            var vA = this.vertices[face.a];
            var vB = this.vertices[face.b];
            var vC = this.vertices[face.c];
            cb.subVectors(vC, vB);
            ab.subVectors(vA, vB);
            cb.cross(ab);
            vertices[face.a].add(cb);
            vertices[face.b].add(cb);
            vertices[face.c].add(cb);
          }
        } else {
          this.computeFaceNormals();

          for (var _f = 0, _fl = this.faces.length; _f < _fl; _f++) {
            var _face = this.faces[_f];

            vertices[_face.a].add(_face.normal);

            vertices[_face.b].add(_face.normal);

            vertices[_face.c].add(_face.normal);
          }
        }

        for (var _v = 0, _vl = this.vertices.length; _v < _vl; _v++) {
          vertices[_v].normalize();
        }

        for (var _f2 = 0, _fl2 = this.faces.length; _f2 < _fl2; _f2++) {
          var _face2 = this.faces[_f2];
          var vertexNormals = _face2.vertexNormals;

          if (vertexNormals.length === 3) {
            vertexNormals[0].copy(vertices[_face2.a]);
            vertexNormals[1].copy(vertices[_face2.b]);
            vertexNormals[2].copy(vertices[_face2.c]);
          } else {
            vertexNormals[0] = vertices[_face2.a].clone();
            vertexNormals[1] = vertices[_face2.b].clone();
            vertexNormals[2] = vertices[_face2.c].clone();
          }
        }

        if (this.faces.length > 0) {
          this.normalsNeedUpdate = true;
        }
      }
    }, {
      key: "computeFlatVertexNormals",
      value: function computeFlatVertexNormals() {
        this.computeFaceNormals();

        for (var f = 0, fl = this.faces.length; f < fl; f++) {
          var face = this.faces[f];
          var vertexNormals = face.vertexNormals;

          if (vertexNormals.length === 3) {
            vertexNormals[0].copy(face.normal);
            vertexNormals[1].copy(face.normal);
            vertexNormals[2].copy(face.normal);
          } else {
            vertexNormals[0] = face.normal.clone();
            vertexNormals[1] = face.normal.clone();
            vertexNormals[2] = face.normal.clone();
          }
        }

        if (this.faces.length > 0) {
          this.normalsNeedUpdate = true;
        }
      }
    }, {
      key: "computeMorphNormals",
      value: function computeMorphNormals() {
        // save original normals
        // - create temp variables on first access
        //   otherwise just copy (for faster repeated calls)
        for (var f = 0, fl = this.faces.length; f < fl; f++) {
          var face = this.faces[f];

          if (!face.__originalFaceNormal) {
            face.__originalFaceNormal = face.normal.clone();
          } else {
            face.__originalFaceNormal.copy(face.normal);
          }

          if (!face.__originalVertexNormals) face.__originalVertexNormals = [];

          for (var i = 0, il = face.vertexNormals.length; i < il; i++) {
            if (!face.__originalVertexNormals[i]) {
              face.__originalVertexNormals[i] = face.vertexNormals[i].clone();
            } else {
              face.__originalVertexNormals[i].copy(face.vertexNormals[i]);
            }
          }
        } // use temp geometry to compute face and vertex normals for each morph


        var tmpGeo = new Geometry();
        tmpGeo.faces = this.faces;

        for (var _i5 = 0, _il2 = this.morphTargets.length; _i5 < _il2; _i5++) {
          // create on first access
          if (!this.morphNormals[_i5]) {
            this.morphNormals[_i5] = {};
            this.morphNormals[_i5].faceNormals = [];
            this.morphNormals[_i5].vertexNormals = [];
            var dstNormalsFace = this.morphNormals[_i5].faceNormals;
            var dstNormalsVertex = this.morphNormals[_i5].vertexNormals;

            for (var _f3 = 0, _fl3 = this.faces.length; _f3 < _fl3; _f3++) {
              var faceNormal = new _three.Vector3();
              var vertexNormals = {
                a: new _three.Vector3(),
                b: new _three.Vector3(),
                c: new _three.Vector3()
              };
              dstNormalsFace.push(faceNormal);
              dstNormalsVertex.push(vertexNormals);
            }
          }

          var morphNormals = this.morphNormals[_i5]; // set vertices to morph target

          tmpGeo.vertices = this.morphTargets[_i5].vertices; // compute morph normals

          tmpGeo.computeFaceNormals();
          tmpGeo.computeVertexNormals(); // store morph normals

          for (var _f4 = 0, _fl4 = this.faces.length; _f4 < _fl4; _f4++) {
            var _face3 = this.faces[_f4];
            var _faceNormal = morphNormals.faceNormals[_f4];
            var _vertexNormals = morphNormals.vertexNormals[_f4];

            _faceNormal.copy(_face3.normal);

            _vertexNormals.a.copy(_face3.vertexNormals[0]);

            _vertexNormals.b.copy(_face3.vertexNormals[1]);

            _vertexNormals.c.copy(_face3.vertexNormals[2]);
          }
        } // restore original normals


        for (var _f5 = 0, _fl5 = this.faces.length; _f5 < _fl5; _f5++) {
          var _face4 = this.faces[_f5];
          _face4.normal = _face4.__originalFaceNormal;
          _face4.vertexNormals = _face4.__originalVertexNormals;
        }
      }
    }, {
      key: "computeBoundingBox",
      value: function computeBoundingBox() {
        if (this.boundingBox === null) {
          this.boundingBox = new _three.Box3();
        }

        this.boundingBox.setFromPoints(this.vertices);
      }
    }, {
      key: "computeBoundingSphere",
      value: function computeBoundingSphere() {
        if (this.boundingSphere === null) {
          this.boundingSphere = new _three.Sphere();
        }

        this.boundingSphere.setFromPoints(this.vertices);
      }
    }, {
      key: "merge",
      value: function merge(geometry, matrix) {
        var materialIndexOffset = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;

        if (!(geometry && geometry.isGeometry)) {
          console.error('THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry);
          return;
        }

        var normalMatrix;
        var vertexOffset = this.vertices.length,
            vertices1 = this.vertices,
            vertices2 = geometry.vertices,
            faces1 = this.faces,
            faces2 = geometry.faces,
            colors1 = this.colors,
            colors2 = geometry.colors;

        if (matrix !== undefined) {
          normalMatrix = new _three.Matrix3().getNormalMatrix(matrix);
        } // vertices


        for (var i = 0, il = vertices2.length; i < il; i++) {
          var vertex = vertices2[i];
          var vertexCopy = vertex.clone();
          if (matrix !== undefined) vertexCopy.applyMatrix4(matrix);
          vertices1.push(vertexCopy);
        } // colors


        for (var _i6 = 0, _il3 = colors2.length; _i6 < _il3; _i6++) {
          colors1.push(colors2[_i6].clone());
        } // faces


        for (var _i7 = 0, _il4 = faces2.length; _i7 < _il4; _i7++) {
          var face = faces2[_i7];
          var normal = void 0,
              color = void 0;
          var faceVertexNormals = face.vertexNormals,
              faceVertexColors = face.vertexColors;
          var faceCopy = new Face3(face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset);
          faceCopy.normal.copy(face.normal);

          if (normalMatrix !== undefined) {
            faceCopy.normal.applyMatrix3(normalMatrix).normalize();
          }

          for (var j = 0, jl = faceVertexNormals.length; j < jl; j++) {
            normal = faceVertexNormals[j].clone();

            if (normalMatrix !== undefined) {
              normal.applyMatrix3(normalMatrix).normalize();
            }

            faceCopy.vertexNormals.push(normal);
          }

          faceCopy.color.copy(face.color);

          for (var _j = 0, _jl = faceVertexColors.length; _j < _jl; _j++) {
            color = faceVertexColors[_j];
            faceCopy.vertexColors.push(color.clone());
          }

          faceCopy.materialIndex = face.materialIndex + materialIndexOffset;
          faces1.push(faceCopy);
        } // uvs


        for (var _i8 = 0, _il5 = geometry.faceVertexUvs.length; _i8 < _il5; _i8++) {
          var faceVertexUvs2 = geometry.faceVertexUvs[_i8];
          if (this.faceVertexUvs[_i8] === undefined) this.faceVertexUvs[_i8] = [];

          for (var _j2 = 0, _jl2 = faceVertexUvs2.length; _j2 < _jl2; _j2++) {
            var uvs2 = faceVertexUvs2[_j2],
                uvsCopy = [];

            for (var k = 0, kl = uvs2.length; k < kl; k++) {
              uvsCopy.push(uvs2[k].clone());
            }

            this.faceVertexUvs[_i8].push(uvsCopy);
          }
        }
      }
    }, {
      key: "mergeMesh",
      value: function mergeMesh(mesh) {
        if (!(mesh && mesh.isMesh)) {
          console.error('THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh);
          return;
        }

        if (mesh.matrixAutoUpdate) mesh.updateMatrix();
        this.merge(mesh.geometry, mesh.matrix);
      }
      /*
       * Checks for duplicate vertices with hashmap.
       * Duplicated vertices are removed
       * and faces' vertices are updated.
       */

    }, {
      key: "mergeVertices",
      value: function mergeVertices() {
        var precisionPoints = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 4;
        var verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)

        var unique = [],
            changes = [];
        var precision = Math.pow(10, precisionPoints);

        for (var i = 0, il = this.vertices.length; i < il; i++) {
          var v = this.vertices[i];
          var key = Math.round(v.x * precision) + '_' + Math.round(v.y * precision) + '_' + Math.round(v.z * precision);

          if (verticesMap[key] === undefined) {
            verticesMap[key] = i;
            unique.push(this.vertices[i]);
            changes[i] = unique.length - 1;
          } else {
            //console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);
            changes[i] = changes[verticesMap[key]];
          }
        } // if faces are completely degenerate after merging vertices, we
        // have to remove them from the geometry.


        var faceIndicesToRemove = [];

        for (var _i9 = 0, _il6 = this.faces.length; _i9 < _il6; _i9++) {
          var face = this.faces[_i9];
          face.a = changes[face.a];
          face.b = changes[face.b];
          face.c = changes[face.c];
          var indices = [face.a, face.b, face.c]; // if any duplicate vertices are found in a Face3
          // we have to remove the face as nothing can be saved

          for (var n = 0; n < 3; n++) {
            if (indices[n] === indices[(n + 1) % 3]) {
              faceIndicesToRemove.push(_i9);
              break;
            }
          }
        }

        for (var _i10 = faceIndicesToRemove.length - 1; _i10 >= 0; _i10--) {
          var idx = faceIndicesToRemove[_i10];
          this.faces.splice(idx, 1);

          for (var j = 0, jl = this.faceVertexUvs.length; j < jl; j++) {
            this.faceVertexUvs[j].splice(idx, 1);
          }
        } // Use unique set of vertices


        var diff = this.vertices.length - unique.length;
        this.vertices = unique;
        return diff;
      }
    }, {
      key: "setFromPoints",
      value: function setFromPoints(points) {
        this.vertices = [];

        for (var i = 0, l = points.length; i < l; i++) {
          var point = points[i];
          this.vertices.push(new _three.Vector3(point.x, point.y, point.z || 0));
        }

        return this;
      }
    }, {
      key: "sortFacesByMaterialIndex",
      value: function sortFacesByMaterialIndex() {
        var faces = this.faces;
        var length = faces.length; // tag faces

        for (var i = 0; i < length; i++) {
          faces[i]._id = i;
        } // sort faces


        function materialIndexSort(a, b) {
          return a.materialIndex - b.materialIndex;
        }

        faces.sort(materialIndexSort); // sort uvs

        var uvs1 = this.faceVertexUvs[0];
        var uvs2 = this.faceVertexUvs[1];
        var newUvs1, newUvs2;
        if (uvs1 && uvs1.length === length) newUvs1 = [];
        if (uvs2 && uvs2.length === length) newUvs2 = [];

        for (var _i11 = 0; _i11 < length; _i11++) {
          var id = faces[_i11]._id;
          if (newUvs1) newUvs1.push(uvs1[id]);
          if (newUvs2) newUvs2.push(uvs2[id]);
        }

        if (newUvs1) this.faceVertexUvs[0] = newUvs1;
        if (newUvs2) this.faceVertexUvs[1] = newUvs2;
      }
    }, {
      key: "toJSON",
      value: function toJSON() {
        var data = {
          metadata: {
            version: 4.5,
            type: 'Geometry',
            generator: 'Geometry.toJSON'
          }
        }; // standard Geometry serialization

        data.uuid = this.uuid;
        data.type = this.type;
        if (this.name !== '') data.name = this.name;

        if (this.parameters !== undefined) {
          var parameters = this.parameters;

          for (var key in parameters) {
            if (parameters[key] !== undefined) data[key] = parameters[key];
          }

          return data;
        }

        var vertices = [];

        for (var i = 0; i < this.vertices.length; i++) {
          var vertex = this.vertices[i];
          vertices.push(vertex.x, vertex.y, vertex.z);
        }

        var faces = [];
        var normals = [];
        var normalsHash = {};
        var colors = [];
        var colorsHash = {};
        var uvs = [];
        var uvsHash = {};

        for (var _i12 = 0; _i12 < this.faces.length; _i12++) {
          var face = this.faces[_i12];
          var hasMaterial = true;
          var hasFaceUv = false; // deprecated

          var hasFaceVertexUv = this.faceVertexUvs[0][_i12] !== undefined;
          var hasFaceNormal = face.normal.length() > 0;
          var hasFaceVertexNormal = face.vertexNormals.length > 0;
          var hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;
          var hasFaceVertexColor = face.vertexColors.length > 0;
          var faceType = 0;
          faceType = setBit(faceType, 0, 0); // isQuad

          faceType = setBit(faceType, 1, hasMaterial);
          faceType = setBit(faceType, 2, hasFaceUv);
          faceType = setBit(faceType, 3, hasFaceVertexUv);
          faceType = setBit(faceType, 4, hasFaceNormal);
          faceType = setBit(faceType, 5, hasFaceVertexNormal);
          faceType = setBit(faceType, 6, hasFaceColor);
          faceType = setBit(faceType, 7, hasFaceVertexColor);
          faces.push(faceType);
          faces.push(face.a, face.b, face.c);
          faces.push(face.materialIndex);

          if (hasFaceVertexUv) {
            var faceVertexUvs = this.faceVertexUvs[0][_i12];
            faces.push(getUvIndex(faceVertexUvs[0]), getUvIndex(faceVertexUvs[1]), getUvIndex(faceVertexUvs[2]));
          }

          if (hasFaceNormal) {
            faces.push(getNormalIndex(face.normal));
          }

          if (hasFaceVertexNormal) {
            var vertexNormals = face.vertexNormals;
            faces.push(getNormalIndex(vertexNormals[0]), getNormalIndex(vertexNormals[1]), getNormalIndex(vertexNormals[2]));
          }

          if (hasFaceColor) {
            faces.push(getColorIndex(face.color));
          }

          if (hasFaceVertexColor) {
            var vertexColors = face.vertexColors;
            faces.push(getColorIndex(vertexColors[0]), getColorIndex(vertexColors[1]), getColorIndex(vertexColors[2]));
          }
        }

        function setBit(value, position, enabled) {
          return enabled ? value | 1 << position : value & ~(1 << position);
        }

        function getNormalIndex(normal) {
          var hash = normal.x.toString() + normal.y.toString() + normal.z.toString();

          if (normalsHash[hash] !== undefined) {
            return normalsHash[hash];
          }

          normalsHash[hash] = normals.length / 3;
          normals.push(normal.x, normal.y, normal.z);
          return normalsHash[hash];
        }

        function getColorIndex(color) {
          var hash = color.r.toString() + color.g.toString() + color.b.toString();

          if (colorsHash[hash] !== undefined) {
            return colorsHash[hash];
          }

          colorsHash[hash] = colors.length;
          colors.push(color.getHex());
          return colorsHash[hash];
        }

        function getUvIndex(uv) {
          var hash = uv.x.toString() + uv.y.toString();

          if (uvsHash[hash] !== undefined) {
            return uvsHash[hash];
          }

          uvsHash[hash] = uvs.length / 2;
          uvs.push(uv.x, uv.y);
          return uvsHash[hash];
        }

        data.data = {};
        data.data.vertices = vertices;
        data.data.normals = normals;
        if (colors.length > 0) data.data.colors = colors;
        if (uvs.length > 0) data.data.uvs = [uvs]; // temporal backward compatibility

        data.data.faces = faces;
        return data;
      }
    }, {
      key: "clone",
      value: function clone() {
        /*
         // Handle primitives
        	 const parameters = this.parameters;
        	 if ( parameters !== undefined ) {
        	 const values = [];
        	 for ( const key in parameters ) {
        	 values.push( parameters[ key ] );
        	 }
        	 const geometry = Object.create( this.constructor.prototype );
         this.constructor.apply( geometry, values );
         return geometry;
        	 }
        	 return new this.constructor().copy( this );
         */
        return new Geometry().copy(this);
      }
    }, {
      key: "copy",
      value: function copy(source) {
        // reset
        this.vertices = [];
        this.colors = [];
        this.faces = [];
        this.faceVertexUvs = [[]];
        this.morphTargets = [];
        this.morphNormals = [];
        this.skinWeights = [];
        this.skinIndices = [];
        this.lineDistances = [];
        this.boundingBox = null;
        this.boundingSphere = null; // name

        this.name = source.name; // vertices

        var vertices = source.vertices;

        for (var i = 0, il = vertices.length; i < il; i++) {
          this.vertices.push(vertices[i].clone());
        } // colors


        var colors = source.colors;

        for (var _i13 = 0, _il7 = colors.length; _i13 < _il7; _i13++) {
          this.colors.push(colors[_i13].clone());
        } // faces


        var faces = source.faces;

        for (var _i14 = 0, _il8 = faces.length; _i14 < _il8; _i14++) {
          this.faces.push(faces[_i14].clone());
        } // face vertex uvs


        for (var _i15 = 0, _il9 = source.faceVertexUvs.length; _i15 < _il9; _i15++) {
          var faceVertexUvs = source.faceVertexUvs[_i15];

          if (this.faceVertexUvs[_i15] === undefined) {
            this.faceVertexUvs[_i15] = [];
          }

          for (var j = 0, jl = faceVertexUvs.length; j < jl; j++) {
            var uvs = faceVertexUvs[j],
                uvsCopy = [];

            for (var k = 0, kl = uvs.length; k < kl; k++) {
              var uv = uvs[k];
              uvsCopy.push(uv.clone());
            }

            this.faceVertexUvs[_i15].push(uvsCopy);
          }
        } // morph targets


        var morphTargets = source.morphTargets;

        for (var _i16 = 0, _il10 = morphTargets.length; _i16 < _il10; _i16++) {
          var morphTarget = {};
          morphTarget.name = morphTargets[_i16].name; // vertices

          if (morphTargets[_i16].vertices !== undefined) {
            morphTarget.vertices = [];

            for (var _j3 = 0, _jl3 = morphTargets[_i16].vertices.length; _j3 < _jl3; _j3++) {
              morphTarget.vertices.push(morphTargets[_i16].vertices[_j3].clone());
            }
          } // normals


          if (morphTargets[_i16].normals !== undefined) {
            morphTarget.normals = [];

            for (var _j4 = 0, _jl4 = morphTargets[_i16].normals.length; _j4 < _jl4; _j4++) {
              morphTarget.normals.push(morphTargets[_i16].normals[_j4].clone());
            }
          }

          this.morphTargets.push(morphTarget);
        } // morph normals


        var morphNormals = source.morphNormals;

        for (var _i17 = 0, _il11 = morphNormals.length; _i17 < _il11; _i17++) {
          var morphNormal = {}; // vertex normals

          if (morphNormals[_i17].vertexNormals !== undefined) {
            morphNormal.vertexNormals = [];

            for (var _j5 = 0, _jl5 = morphNormals[_i17].vertexNormals.length; _j5 < _jl5; _j5++) {
              var srcVertexNormal = morphNormals[_i17].vertexNormals[_j5];
              var destVertexNormal = {};
              destVertexNormal.a = srcVertexNormal.a.clone();
              destVertexNormal.b = srcVertexNormal.b.clone();
              destVertexNormal.c = srcVertexNormal.c.clone();
              morphNormal.vertexNormals.push(destVertexNormal);
            }
          } // face normals


          if (morphNormals[_i17].faceNormals !== undefined) {
            morphNormal.faceNormals = [];

            for (var _j6 = 0, _jl6 = morphNormals[_i17].faceNormals.length; _j6 < _jl6; _j6++) {
              morphNormal.faceNormals.push(morphNormals[_i17].faceNormals[_j6].clone());
            }
          }

          this.morphNormals.push(morphNormal);
        } // skin weights


        var skinWeights = source.skinWeights;

        for (var _i18 = 0, _il12 = skinWeights.length; _i18 < _il12; _i18++) {
          this.skinWeights.push(skinWeights[_i18].clone());
        } // skin indices


        var skinIndices = source.skinIndices;

        for (var _i19 = 0, _il13 = skinIndices.length; _i19 < _il13; _i19++) {
          this.skinIndices.push(skinIndices[_i19].clone());
        } // line distances


        var lineDistances = source.lineDistances;

        for (var _i20 = 0, _il14 = lineDistances.length; _i20 < _il14; _i20++) {
          this.lineDistances.push(lineDistances[_i20]);
        } // bounding box


        var boundingBox = source.boundingBox;

        if (boundingBox !== null) {
          this.boundingBox = boundingBox.clone();
        } // bounding sphere


        var boundingSphere = source.boundingSphere;

        if (boundingSphere !== null) {
          this.boundingSphere = boundingSphere.clone();
        } // update flags


        this.elementsNeedUpdate = source.elementsNeedUpdate;
        this.verticesNeedUpdate = source.verticesNeedUpdate;
        this.uvsNeedUpdate = source.uvsNeedUpdate;
        this.normalsNeedUpdate = source.normalsNeedUpdate;
        this.colorsNeedUpdate = source.colorsNeedUpdate;
        this.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate;
        this.groupsNeedUpdate = source.groupsNeedUpdate;
        return this;
      }
    }, {
      key: "toBufferGeometry",
      value: function toBufferGeometry() {
        var geometry = new DirectGeometry().fromGeometry(this);
        var buffergeometry = new _three.BufferGeometry();
        var positions = new Float32Array(geometry.vertices.length * 3);
        buffergeometry.setAttribute('position', new _three.BufferAttribute(positions, 3).copyVector3sArray(geometry.vertices));

        if (geometry.normals.length > 0) {
          var normals = new Float32Array(geometry.normals.length * 3);
          buffergeometry.setAttribute('normal', new _three.BufferAttribute(normals, 3).copyVector3sArray(geometry.normals));
        }

        if (geometry.colors.length > 0) {
          var colors = new Float32Array(geometry.colors.length * 3);
          buffergeometry.setAttribute('color', new _three.BufferAttribute(colors, 3).copyColorsArray(geometry.colors));
        }

        if (geometry.uvs.length > 0) {
          var uvs = new Float32Array(geometry.uvs.length * 2);
          buffergeometry.setAttribute('uv', new _three.BufferAttribute(uvs, 2).copyVector2sArray(geometry.uvs));
        }

        if (geometry.uvs2.length > 0) {
          var uvs2 = new Float32Array(geometry.uvs2.length * 2);
          buffergeometry.setAttribute('uv2', new _three.BufferAttribute(uvs2, 2).copyVector2sArray(geometry.uvs2));
        } // groups


        buffergeometry.groups = geometry.groups; // morphs

        for (var name in geometry.morphTargets) {
          var array = [];
          var morphTargets = geometry.morphTargets[name];

          for (var i = 0, l = morphTargets.length; i < l; i++) {
            var morphTarget = morphTargets[i];
            var attribute = new _three.Float32BufferAttribute(morphTarget.data.length * 3, 3);
            attribute.name = morphTarget.name;
            array.push(attribute.copyVector3sArray(morphTarget.data));
          }

          buffergeometry.morphAttributes[name] = array;
        } // skinning


        if (geometry.skinIndices.length > 0) {
          var skinIndices = new _three.Float32BufferAttribute(geometry.skinIndices.length * 4, 4);
          buffergeometry.setAttribute('skinIndex', skinIndices.copyVector4sArray(geometry.skinIndices));
        }

        if (geometry.skinWeights.length > 0) {
          var skinWeights = new _three.Float32BufferAttribute(geometry.skinWeights.length * 4, 4);
          buffergeometry.setAttribute('skinWeight', skinWeights.copyVector4sArray(geometry.skinWeights));
        } //


        if (geometry.boundingSphere !== null) {
          buffergeometry.boundingSphere = geometry.boundingSphere.clone();
        }

        if (geometry.boundingBox !== null) {
          buffergeometry.boundingBox = geometry.boundingBox.clone();
        }

        return buffergeometry;
      }
    }, {
      key: "computeTangents",
      value: function computeTangents() {
        console.error('THREE.Geometry: .computeTangents() has been removed.');
      }
    }, {
      key: "computeLineDistances",
      value: function computeLineDistances() {
        console.error('THREE.Geometry: .computeLineDistances() has been removed. Use THREE.Line.computeLineDistances() instead.');
      }
    }, {
      key: "applyMatrix",
      value: function applyMatrix(matrix) {
        console.warn('THREE.Geometry: .applyMatrix() has been renamed to .applyMatrix4().');
        return this.applyMatrix4(matrix);
      }
    }, {
      key: "dispose",
      value: function dispose() {
        this.dispatchEvent({
          type: 'dispose'
        });
      }
    }], [{
      key: "createBufferGeometryFromObject",
      value: function createBufferGeometryFromObject(object) {
        var buffergeometry = new _three.BufferGeometry();
        var geometry = object.geometry;

        if (object.isPoints || object.isLine) {
          var positions = new _three.Float32BufferAttribute(geometry.vertices.length * 3, 3);
          var colors = new _three.Float32BufferAttribute(geometry.colors.length * 3, 3);
          buffergeometry.setAttribute('position', positions.copyVector3sArray(geometry.vertices));
          buffergeometry.setAttribute('color', colors.copyColorsArray(geometry.colors));

          if (geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length) {
            var lineDistances = new _three.Float32BufferAttribute(geometry.lineDistances.length, 1);
            buffergeometry.setAttribute('lineDistance', lineDistances.copyArray(geometry.lineDistances));
          }

          if (geometry.boundingSphere !== null) {
            buffergeometry.boundingSphere = geometry.boundingSphere.clone();
          }

          if (geometry.boundingBox !== null) {
            buffergeometry.boundingBox = geometry.boundingBox.clone();
          }
        } else if (object.isMesh) {
          buffergeometry = geometry.toBufferGeometry();
        }

        return buffergeometry;
      }
    }]);

    return Geometry;
  }(_three.EventDispatcher);

  _exports.Geometry = Geometry;
  Geometry.prototype.isGeometry = true;

  var DirectGeometry = /*#__PURE__*/function () {
    function DirectGeometry() {
      _classCallCheck(this, DirectGeometry);

      this.vertices = [];
      this.normals = [];
      this.colors = [];
      this.uvs = [];
      this.uvs2 = [];
      this.groups = [];
      this.morphTargets = {};
      this.skinWeights = [];
      this.skinIndices = []; // this.lineDistances = [];

      this.boundingBox = null;
      this.boundingSphere = null; // update flags

      this.verticesNeedUpdate = false;
      this.normalsNeedUpdate = false;
      this.colorsNeedUpdate = false;
      this.uvsNeedUpdate = false;
      this.groupsNeedUpdate = false;
    }

    _createClass(DirectGeometry, [{
      key: "computeGroups",
      value: function computeGroups(geometry) {
        var groups = [];
        var group, i;
        var materialIndex = undefined;
        var faces = geometry.faces;

        for (i = 0; i < faces.length; i++) {
          var face = faces[i]; // materials

          if (face.materialIndex !== materialIndex) {
            materialIndex = face.materialIndex;

            if (group !== undefined) {
              group.count = i * 3 - group.start;
              groups.push(group);
            }

            group = {
              start: i * 3,
              materialIndex: materialIndex
            };
          }
        }

        if (group !== undefined) {
          group.count = i * 3 - group.start;
          groups.push(group);
        }

        this.groups = groups;
      }
    }, {
      key: "fromGeometry",
      value: function fromGeometry(geometry) {
        var faces = geometry.faces;
        var vertices = geometry.vertices;
        var faceVertexUvs = geometry.faceVertexUvs;
        var hasFaceVertexUv = faceVertexUvs[0] && faceVertexUvs[0].length > 0;
        var hasFaceVertexUv2 = faceVertexUvs[1] && faceVertexUvs[1].length > 0; // morphs

        var morphTargets = geometry.morphTargets;
        var morphTargetsLength = morphTargets.length;
        var morphTargetsPosition;

        if (morphTargetsLength > 0) {
          morphTargetsPosition = [];

          for (var i = 0; i < morphTargetsLength; i++) {
            morphTargetsPosition[i] = {
              name: morphTargets[i].name,
              data: []
            };
          }

          this.morphTargets.position = morphTargetsPosition;
        }

        var morphNormals = geometry.morphNormals;
        var morphNormalsLength = morphNormals.length;
        var morphTargetsNormal;

        if (morphNormalsLength > 0) {
          morphTargetsNormal = [];

          for (var _i21 = 0; _i21 < morphNormalsLength; _i21++) {
            morphTargetsNormal[_i21] = {
              name: morphNormals[_i21].name,
              data: []
            };
          }

          this.morphTargets.normal = morphTargetsNormal;
        } // skins


        var skinIndices = geometry.skinIndices;
        var skinWeights = geometry.skinWeights;
        var hasSkinIndices = skinIndices.length === vertices.length;
        var hasSkinWeights = skinWeights.length === vertices.length; //

        if (vertices.length > 0 && faces.length === 0) {
          console.error('THREE.DirectGeometry: Faceless geometries are not supported.');
        }

        for (var _i22 = 0; _i22 < faces.length; _i22++) {
          var face = faces[_i22];
          this.vertices.push(vertices[face.a], vertices[face.b], vertices[face.c]);
          var vertexNormals = face.vertexNormals;

          if (vertexNormals.length === 3) {
            this.normals.push(vertexNormals[0], vertexNormals[1], vertexNormals[2]);
          } else {
            var normal = face.normal;
            this.normals.push(normal, normal, normal);
          }

          var vertexColors = face.vertexColors;

          if (vertexColors.length === 3) {
            this.colors.push(vertexColors[0], vertexColors[1], vertexColors[2]);
          } else {
            var color = face.color;
            this.colors.push(color, color, color);
          }

          if (hasFaceVertexUv === true) {
            var vertexUvs = faceVertexUvs[0][_i22];

            if (vertexUvs !== undefined) {
              this.uvs.push(vertexUvs[0], vertexUvs[1], vertexUvs[2]);
            } else {
              console.warn('THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', _i22);
              this.uvs.push(new _three.Vector2(), new _three.Vector2(), new _three.Vector2());
            }
          }

          if (hasFaceVertexUv2 === true) {
            var _vertexUvs = faceVertexUvs[1][_i22];

            if (_vertexUvs !== undefined) {
              this.uvs2.push(_vertexUvs[0], _vertexUvs[1], _vertexUvs[2]);
            } else {
              console.warn('THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', _i22);
              this.uvs2.push(new _three.Vector2(), new _three.Vector2(), new _three.Vector2());
            }
          } // morphs


          for (var j = 0; j < morphTargetsLength; j++) {
            var morphTarget = morphTargets[j].vertices;
            morphTargetsPosition[j].data.push(morphTarget[face.a], morphTarget[face.b], morphTarget[face.c]);
          }

          for (var _j7 = 0; _j7 < morphNormalsLength; _j7++) {
            var morphNormal = morphNormals[_j7].vertexNormals[_i22];

            morphTargetsNormal[_j7].data.push(morphNormal.a, morphNormal.b, morphNormal.c);
          } // skins


          if (hasSkinIndices) {
            this.skinIndices.push(skinIndices[face.a], skinIndices[face.b], skinIndices[face.c]);
          }

          if (hasSkinWeights) {
            this.skinWeights.push(skinWeights[face.a], skinWeights[face.b], skinWeights[face.c]);
          }
        }

        this.computeGroups(geometry);
        this.verticesNeedUpdate = geometry.verticesNeedUpdate;
        this.normalsNeedUpdate = geometry.normalsNeedUpdate;
        this.colorsNeedUpdate = geometry.colorsNeedUpdate;
        this.uvsNeedUpdate = geometry.uvsNeedUpdate;
        this.groupsNeedUpdate = geometry.groupsNeedUpdate;

        if (geometry.boundingSphere !== null) {
          this.boundingSphere = geometry.boundingSphere.clone();
        }

        if (geometry.boundingBox !== null) {
          this.boundingBox = geometry.boundingBox.clone();
        }

        return this;
      }
    }]);

    return DirectGeometry;
  }();

  var Face3 = /*#__PURE__*/function () {
    function Face3(a, b, c, normal, color) {
      var materialIndex = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;

      _classCallCheck(this, Face3);

      this.a = a;
      this.b = b;
      this.c = c;
      this.normal = normal && normal.isVector3 ? normal : new _three.Vector3();
      this.vertexNormals = Array.isArray(normal) ? normal : [];
      this.color = color && color.isColor ? color : new _three.Color();
      this.vertexColors = Array.isArray(color) ? color : [];
      this.materialIndex = materialIndex;
    }

    _createClass(Face3, [{
      key: "clone",
      value: function clone() {
        return new this.constructor().copy(this);
      }
    }, {
      key: "copy",
      value: function copy(source) {
        this.a = source.a;
        this.b = source.b;
        this.c = source.c;
        this.normal.copy(source.normal);
        this.color.copy(source.color);
        this.materialIndex = source.materialIndex;

        for (var i = 0, il = source.vertexNormals.length; i < il; i++) {
          this.vertexNormals[i] = source.vertexNormals[i].clone();
        }

        for (var _i23 = 0, _il15 = source.vertexColors.length; _i23 < _il15; _i23++) {
          this.vertexColors[_i23] = source.vertexColors[_i23].clone();
        }

        return this;
      }
    }]);

    return Face3;
  }();

  _exports.Face3 = Face3;
});