(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.RoundedBoxGeometry = mod.exports;
  }
})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports, _three) {
  "use strict";

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

  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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

  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 _tempNormal = new _three.Vector3();

  function getUv(faceDirVector, normal, uvAxis, projectionAxis, radius, sideLength) {
    var totArcLength = 2 * Math.PI * radius / 4; // length of the planes between the arcs on each axis

    var centerLength = Math.max(sideLength - 2 * radius, 0);
    var halfArc = Math.PI / 4; // Get the vector projected onto the Y plane

    _tempNormal.copy(normal);

    _tempNormal[projectionAxis] = 0;

    _tempNormal.normalize(); // total amount of UV space alloted to a single arc


    var arcUvRatio = 0.5 * totArcLength / (totArcLength + centerLength); // the distance along one arc the point is at

    var arcAngleRatio = 1.0 - _tempNormal.angleTo(faceDirVector) / halfArc;

    if (Math.sign(_tempNormal[uvAxis]) === 1) {
      return arcAngleRatio * arcUvRatio;
    } else {
      // total amount of UV space alloted to the plane between the arcs
      var lenUv = centerLength / (totArcLength + centerLength);
      return lenUv + arcUvRatio + arcUvRatio * (1.0 - arcAngleRatio);
    }
  }

  var RoundedBoxGeometry = /*#__PURE__*/function (_BoxGeometry) {
    _inherits(RoundedBoxGeometry, _BoxGeometry);

    var _super = _createSuper(RoundedBoxGeometry);

    function RoundedBoxGeometry() {
      var _this;

      var width = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
      var height = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
      var depth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
      var segments = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 2;
      var radius = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0.1;

      _classCallCheck(this, RoundedBoxGeometry);

      // ensure segments is odd so we have a plane connecting the rounded corners
      segments = segments * 2 + 1; // ensure radius isn't bigger than shortest side

      radius = Math.min(width / 2, height / 2, depth / 2, radius);
      _this = _super.call(this, 1, 1, 1, segments, segments, segments); // if we just have one segment we're the same as a regular box

      if (segments === 1) return _possibleConstructorReturn(_this);

      var geometry2 = _this.toNonIndexed();

      _this.index = null;
      _this.attributes.position = geometry2.attributes.position;
      _this.attributes.normal = geometry2.attributes.normal;
      _this.attributes.uv = geometry2.attributes.uv; //

      var position = new _three.Vector3();
      var normal = new _three.Vector3();
      var box = new _three.Vector3(width, height, depth).divideScalar(2).subScalar(radius);
      var positions = _this.attributes.position.array;
      var normals = _this.attributes.normal.array;
      var uvs = _this.attributes.uv.array;
      var faceTris = positions.length / 6;
      var faceDirVector = new _three.Vector3();
      var halfSegmentSize = 0.5 / segments;

      for (var i = 0, j = 0; i < positions.length; i += 3, j += 2) {
        position.fromArray(positions, i);
        normal.copy(position);
        normal.x -= Math.sign(normal.x) * halfSegmentSize;
        normal.y -= Math.sign(normal.y) * halfSegmentSize;
        normal.z -= Math.sign(normal.z) * halfSegmentSize;
        normal.normalize();
        positions[i + 0] = box.x * Math.sign(position.x) + normal.x * radius;
        positions[i + 1] = box.y * Math.sign(position.y) + normal.y * radius;
        positions[i + 2] = box.z * Math.sign(position.z) + normal.z * radius;
        normals[i + 0] = normal.x;
        normals[i + 1] = normal.y;
        normals[i + 2] = normal.z;
        var side = Math.floor(i / faceTris);

        switch (side) {
          case 0:
            // right
            // generate UVs along Z then Y
            faceDirVector.set(1, 0, 0);
            uvs[j + 0] = getUv(faceDirVector, normal, 'z', 'y', radius, depth);
            uvs[j + 1] = 1.0 - getUv(faceDirVector, normal, 'y', 'z', radius, height);
            break;

          case 1:
            // left
            // generate UVs along Z then Y
            faceDirVector.set(-1, 0, 0);
            uvs[j + 0] = 1.0 - getUv(faceDirVector, normal, 'z', 'y', radius, depth);
            uvs[j + 1] = 1.0 - getUv(faceDirVector, normal, 'y', 'z', radius, height);
            break;

          case 2:
            // top
            // generate UVs along X then Z
            faceDirVector.set(0, 1, 0);
            uvs[j + 0] = 1.0 - getUv(faceDirVector, normal, 'x', 'z', radius, width);
            uvs[j + 1] = getUv(faceDirVector, normal, 'z', 'x', radius, depth);
            break;

          case 3:
            // bottom
            // generate UVs along X then Z
            faceDirVector.set(0, -1, 0);
            uvs[j + 0] = 1.0 - getUv(faceDirVector, normal, 'x', 'z', radius, width);
            uvs[j + 1] = 1.0 - getUv(faceDirVector, normal, 'z', 'x', radius, depth);
            break;

          case 4:
            // front
            // generate UVs along X then Y
            faceDirVector.set(0, 0, 1);
            uvs[j + 0] = 1.0 - getUv(faceDirVector, normal, 'x', 'y', radius, width);
            uvs[j + 1] = 1.0 - getUv(faceDirVector, normal, 'y', 'x', radius, height);
            break;

          case 5:
            // back
            // generate UVs along X then Y
            faceDirVector.set(0, 0, -1);
            uvs[j + 0] = getUv(faceDirVector, normal, 'x', 'y', radius, width);
            uvs[j + 1] = 1.0 - getUv(faceDirVector, normal, 'y', 'x', radius, height);
            break;
        }
      }

      return _this;
    }

    return _createClass(RoundedBoxGeometry);
  }(_three.BoxGeometry);

  _exports.RoundedBoxGeometry = RoundedBoxGeometry;
});