"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;
var _cesium = require("cesium");
var radiusScratch = new _cesium.Cartesian2();
var normalScratch = new _cesium.Cartesian3();
var bitangentScratch = new _cesium.Cartesian3();
var tangentScratch = new _cesium.Cartesian3();
var positionScratch = new _cesium.Cartesian3();
var getPositions = function getPositions(topRadius, slices) {
  var positions = new Float64Array(slices * 2);
  var i;
  var index = 0;
  var angleStep = 2 * Math.PI / slices; // 每个切片的角
  for (i = 0; i < slices; i++) {
    var angle = i * angleStep;
    var x = Math.cos(angle) * 0.25 + 0.25;
    var y = Math.sin(angle) * 0.25 + 0.75;
    positions[index++] = x;
    positions[index++] = y;
  }
  console.log("positions:", positions);
  return positions;
};

/**
 * A description of a cylinder.
 *
 * @alias CylinderGeometry
 * @constructor
 *
 * @param {Object} options Object with the following properties:
 * @param {Number} options.length The length of the cylinder.
 * @param {Number} options.topRadius The radius of the top of the cylinder.
 * @param {Number} options.bottomRadius The radius of the bottom of the cylinder.
 * @param {Number} [options.slices=128] The number of edges around the perimeter of the cylinder.
 * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed.
 *
 * @exception {DeveloperError} options.slices must be greater than or equal to 3.
 *
 * @see CylinderGeometry.createGeometry
 *
 * @example
 * // create cylinder geometry
 * const cylinder = new Cesium.CylinderGeometry({
 *     length: 200000,
 *     topRadius: 80000,
 *     bottomRadius: 200000,
 * });
 * const geometry = Cesium.CylinderGeometry.createGeometry(cylinder);
 */
function CylinderGeometry(options) {
  options = (0, _cesium.defaultValue)(options, _cesium.defaultValue.EMPTY_OBJECT);
  var length = options.length;
  var topRadius = options.topRadius;
  var bottomRadius = options.bottomRadius;
  var vertexFormat = (0, _cesium.defaultValue)(options.vertexFormat, _cesium.VertexFormat.DEFAULT);
  var slices = (0, _cesium.defaultValue)(options.slices, 128);

  //>>includeStart('debug', pragmas.debug);
  if (!(0, _cesium.defined)(length)) {
    throw new _cesium.DeveloperError("options.length must be defined.");
  }
  if (!(0, _cesium.defined)(topRadius)) {
    throw new _cesium.DeveloperError("options.topRadius must be defined.");
  }
  if (!(0, _cesium.defined)(bottomRadius)) {
    throw new _cesium.DeveloperError("options.bottomRadius must be defined.");
  }
  if (slices < 3) {
    throw new _cesium.DeveloperError("options.slices must be greater than or equal to 3.");
  }
  if ((0, _cesium.defined)(options.offsetAttribute) && options.offsetAttribute === _cesium.GeometryOffsetAttribute.TOP) {
    throw new _cesium.DeveloperError("GeometryOffsetAttribute.TOP is not a supported options.offsetAttribute for this geometry.");
  }
  //>>includeEnd('debug');

  this._length = length;
  this._topRadius = topRadius;
  this._bottomRadius = bottomRadius;
  this._vertexFormat = _cesium.VertexFormat.clone(vertexFormat);
  this._slices = slices;
  this._offsetAttribute = options.offsetAttribute;
  this._workerName = "createCylinderGeometry";
}

/**
 * The number of elements used to pack the object into an array.
 * @type {Number}
 */
CylinderGeometry.packedLength = _cesium.VertexFormat.packedLength + 5;

/**
 * Stores the provided instance into the provided array.
 *
 * @param {CylinderGeometry} value The value to pack.
 * @param {Number[]} array The array to pack into.
 * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements.
 *
 * @returns {Number[]} The array that was packed into
 */
CylinderGeometry.pack = function (value, array, startingIndex) {
  //>>includeStart('debug', pragmas.debug);
  if (!(0, _cesium.defined)(value)) {
    throw new _cesium.DeveloperError("value is required");
  }
  if (!(0, _cesium.defined)(array)) {
    throw new _cesium.DeveloperError("array is required");
  }
  //>>includeEnd('debug');

  startingIndex = (0, _cesium.defaultValue)(startingIndex, 0);
  _cesium.VertexFormat.pack(value._vertexFormat, array, startingIndex);
  startingIndex += _cesium.VertexFormat.packedLength;
  array[startingIndex++] = value._length;
  array[startingIndex++] = value._topRadius;
  array[startingIndex++] = value._bottomRadius;
  array[startingIndex++] = value._slices;
  array[startingIndex] = (0, _cesium.defaultValue)(value._offsetAttribute, -1);
  return array;
};
var scratchVertexFormat = new _cesium.VertexFormat();
var scratchOptions = {
  vertexFormat: scratchVertexFormat,
  length: undefined,
  topRadius: undefined,
  bottomRadius: undefined,
  slices: undefined,
  offsetAttribute: undefined
};

/**
 * Retrieves an instance from a packed array.
 *
 * @param {Number[]} array The packed array.
 * @param {Number} [startingIndex=0] The starting index of the element to be unpacked.
 * @param {CylinderGeometry} [result] The object into which to store the result.
 * @returns {CylinderGeometry} The modified result parameter or a new CylinderGeometry instance if one was not provided.
 */
CylinderGeometry.unpack = function (array, startingIndex, result) {
  //>>includeStart('debug', pragmas.debug);
  if (!(0, _cesium.defined)(array)) {
    throw new _cesium.DeveloperError("array is required");
  }
  //>>includeEnd('debug');

  startingIndex = (0, _cesium.defaultValue)(startingIndex, 0);
  var vertexFormat = _cesium.VertexFormat.unpack(array, startingIndex, scratchVertexFormat);
  startingIndex += _cesium.VertexFormat.packedLength;
  var length = array[startingIndex++];
  var topRadius = array[startingIndex++];
  var bottomRadius = array[startingIndex++];
  var slices = array[startingIndex++];
  var offsetAttribute = array[startingIndex];
  if (!(0, _cesium.defined)(result)) {
    scratchOptions.length = length;
    scratchOptions.topRadius = topRadius;
    scratchOptions.bottomRadius = bottomRadius;
    scratchOptions.slices = slices;
    scratchOptions.offsetAttribute = offsetAttribute === -1 ? undefined : offsetAttribute;
    return new CylinderGeometry(scratchOptions);
  }
  result._vertexFormat = _cesium.VertexFormat.clone(vertexFormat, result._vertexFormat);
  result._length = length;
  result._topRadius = topRadius;
  result._bottomRadius = bottomRadius;
  result._slices = slices;
  result._offsetAttribute = offsetAttribute === -1 ? undefined : offsetAttribute;
  return result;
};

/**
 * Computes the geometric representation of a cylinder, including its vertices, indices, and a bounding sphere.
 *
 * @param {CylinderGeometry} cylinderGeometry A description of the cylinder.
 * @returns {Geometry|undefined} The computed vertices and indices.
 */
CylinderGeometry.createGeometry = function (cylinderGeometry) {
  var length = cylinderGeometry._length;
  var topRadius = cylinderGeometry._topRadius;
  var bottomRadius = cylinderGeometry._bottomRadius;
  var vertexFormat = cylinderGeometry._vertexFormat;
  var slices = cylinderGeometry._slices;
  if (length <= 0 || topRadius < 0 || bottomRadius < 0 || topRadius === 0 && bottomRadius === 0) {
    return;
  }

  /**
   * slices 表示圆柱体侧面的切片数。
   * twoSlices 是 slices 的两倍，即 2 * slices。
   * 这个值通常用于表示圆柱体侧面的顶点数，因为每个切片有两个顶点（一个在底部，一个在顶部）
   */
  var twoSlices = slices + slices;

  /**
   * threeSlices 是 slices 加上 twoSlices，即 3 * slices。
   * 这个值可能用于表示圆柱体侧面加上顶面或底面的顶点数。具体用途取决于后续的逻辑
   */
  var threeSlices = slices + twoSlices;

  /**
   * numVertices 是 twoSlices 的两倍，即 4 * slices。
   * 这个值表示圆柱体侧面的顶点数。每个切片有两个顶点（一个在底部，一个在顶部），因此总共有 2 * slices 个顶点在底部，2 * slices 个顶点在顶部，合计 4 * slices 个顶点。
   */
  var numVertices = twoSlices + twoSlices;
  var positions = _cesium.CylinderGeometryLibrary.computePositions(length, topRadius, bottomRadius, slices, true);
  var st = vertexFormat.st ? new Float32Array(numVertices * 2) : undefined;
  var normals = vertexFormat.normal ? new Float32Array(numVertices * 3) : undefined;
  var tangents = vertexFormat.tangent ? new Float32Array(numVertices * 3) : undefined;
  var bitangents = vertexFormat.bitangent ? new Float32Array(numVertices * 3) : undefined;
  var i;
  var computeNormal = vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent;
  if (computeNormal) {
    var computeTangent = vertexFormat.tangent || vertexFormat.bitangent;
    var normalIndex = 0;
    var tangentIndex = 0;
    var bitangentIndex = 0;
    var theta = Math.atan2(bottomRadius - topRadius, length);
    var normal = normalScratch;
    normal.z = Math.sin(theta);
    var normalScale = Math.cos(theta);
    var tangent = tangentScratch;
    var bitangent = bitangentScratch;

    // 计算圆柱体侧面的法线（normal）、切线（tangent）和副切线（bitangent）向量
    for (i = 0; i < slices; i++) {
      var angle = i / slices * _cesium.Math.TWO_PI;
      var x = normalScale * Math.cos(angle);
      var y = normalScale * Math.sin(angle);
      if (computeNormal) {
        normal.x = x;
        normal.y = y;
        if (computeTangent) {
          tangent = _cesium.Cartesian3.normalize(_cesium.Cartesian3.cross(_cesium.Cartesian3.UNIT_Z, normal, tangent), tangent);
        }
        if (vertexFormat.normal) {
          normals[normalIndex++] = normal.x;
          normals[normalIndex++] = normal.y;
          normals[normalIndex++] = normal.z;
          normals[normalIndex++] = normal.x;
          normals[normalIndex++] = normal.y;
          normals[normalIndex++] = normal.z;
        }
        if (vertexFormat.tangent) {
          tangents[tangentIndex++] = tangent.x;
          tangents[tangentIndex++] = tangent.y;
          tangents[tangentIndex++] = tangent.z;
          tangents[tangentIndex++] = tangent.x;
          tangents[tangentIndex++] = tangent.y;
          tangents[tangentIndex++] = tangent.z;
        }
        if (vertexFormat.bitangent) {
          bitangent = _cesium.Cartesian3.normalize(_cesium.Cartesian3.cross(normal, tangent, bitangent), bitangent);
          bitangents[bitangentIndex++] = bitangent.x;
          bitangents[bitangentIndex++] = bitangent.y;
          bitangents[bitangentIndex++] = bitangent.z;
          bitangents[bitangentIndex++] = bitangent.x;
          bitangents[bitangentIndex++] = bitangent.y;
          bitangents[bitangentIndex++] = bitangent.z;
        }
      }
    }

    // 计算圆柱体顶面的法线（normal）、切线（tangent）和副切线（bitangent）向量
    for (i = 0; i < slices; i++) {
      if (vertexFormat.normal) {
        normals[normalIndex++] = 0;
        normals[normalIndex++] = 0;
        normals[normalIndex++] = -1;
      }
      if (vertexFormat.tangent) {
        tangents[tangentIndex++] = 1;
        tangents[tangentIndex++] = 0;
        tangents[tangentIndex++] = 0;
      }
      if (vertexFormat.bitangent) {
        bitangents[bitangentIndex++] = 0;
        bitangents[bitangentIndex++] = -1;
        bitangents[bitangentIndex++] = 0;
      }
    }

    // 计算圆柱体底面的法线（normal）、切线（tangent）和副切线（bitangent）向量
    for (i = 0; i < slices; i++) {
      if (vertexFormat.normal) {
        normals[normalIndex++] = 0;
        normals[normalIndex++] = 0;
        normals[normalIndex++] = 1;
      }
      if (vertexFormat.tangent) {
        tangents[tangentIndex++] = 1;
        tangents[tangentIndex++] = 0;
        tangents[tangentIndex++] = 0;
      }
      if (vertexFormat.bitangent) {
        bitangents[bitangentIndex++] = 0;
        bitangents[bitangentIndex++] = 1;
        bitangents[bitangentIndex++] = 0;
      }
    }
  }
  var numIndices = 12 * slices - 12;
  var indices = _cesium.IndexDatatype.createTypedArray(numVertices, numIndices);
  var index = 0;
  var j = 0;
  for (i = 0; i < slices - 1; i++) {
    indices[index++] = j;
    indices[index++] = j + 2;
    indices[index++] = j + 3;
    indices[index++] = j;
    indices[index++] = j + 3;
    indices[index++] = j + 1;
    j += 2;
  }
  indices[index++] = twoSlices - 2;
  indices[index++] = 0;
  indices[index++] = 1;
  indices[index++] = twoSlices - 2;
  indices[index++] = 1;
  indices[index++] = twoSlices - 1;
  for (i = 1; i < slices - 1; i++) {
    indices[index++] = twoSlices + i + 1;
    indices[index++] = twoSlices + i;
    indices[index++] = twoSlices;
  }
  for (i = 1; i < slices - 1; i++) {
    indices[index++] = threeSlices;
    indices[index++] = threeSlices + i;
    indices[index++] = threeSlices + i + 1;
  }
  var textureCoordIndex = 0;
  if (vertexFormat.st) {
    // 填充侧面纹理坐标
    for (var _i = 0; _i < slices; _i++) {
      var u = _i / slices; // U 坐标从 0 到 1
      var v = 0; // V 坐标为 0，表示底部
      st[textureCoordIndex++] = u;
      st[textureCoordIndex++] = v;
      var v2 = 0.5; // V 坐标为 0.5，表示顶部
      st[textureCoordIndex++] = u;
      st[textureCoordIndex++] = v2;
    }

    // 填充顶面纹理坐标
    for (var _i2 = 0; _i2 < slices; _i2++) {
      var _u = _i2 / slices; // U 坐标从 0 到 1
      var _v = 0.5 + 0.5 * (_i2 / slices); // V 坐标从 0.5 到 0.75，表示顶面
      st[textureCoordIndex++] = _u;
      st[textureCoordIndex++] = _v;
    }

    // 填充顶面纹理坐标
    var po = getPositions(topRadius, slices);
    for (i = 0; i < po.length; i++) {
      var s = po[i];
      st[textureCoordIndex++] = s;
    }
  }
  var attributes = new _cesium.GeometryAttributes();
  if (vertexFormat.position) {
    attributes.position = new _cesium.GeometryAttribute({
      componentDatatype: _cesium.ComponentDatatype.DOUBLE,
      componentsPerAttribute: 3,
      values: positions
    });
  }
  if (vertexFormat.normal) {
    attributes.normal = new _cesium.GeometryAttribute({
      componentDatatype: _cesium.ComponentDatatype.FLOAT,
      componentsPerAttribute: 3,
      values: normals
    });
  }
  if (vertexFormat.tangent) {
    attributes.tangent = new _cesium.GeometryAttribute({
      componentDatatype: _cesium.ComponentDatatype.FLOAT,
      componentsPerAttribute: 3,
      values: tangents
    });
  }
  if (vertexFormat.bitangent) {
    attributes.bitangent = new _cesium.GeometryAttribute({
      componentDatatype: _cesium.ComponentDatatype.FLOAT,
      componentsPerAttribute: 3,
      values: bitangents
    });
  }
  if (vertexFormat.st) {
    attributes.st = new _cesium.GeometryAttribute({
      componentDatatype: _cesium.ComponentDatatype.FLOAT,
      componentsPerAttribute: 2,
      values: st
    });
  }
  radiusScratch.x = length * 0.5;
  radiusScratch.y = Math.max(bottomRadius, topRadius);
  var boundingSphere = new _cesium.BoundingSphere(_cesium.Cartesian3.ZERO, _cesium.Cartesian2.magnitude(radiusScratch));
  if ((0, _cesium.defined)(cylinderGeometry._offsetAttribute)) {
    length = positions.length;
    var applyOffset = new Uint8Array(length / 3);
    var offsetValue = cylinderGeometry._offsetAttribute === _cesium.GeometryOffsetAttribute.NONE ? 0 : 1;
    (0, _cesium.arrayFill)(applyOffset, offsetValue);
    attributes.applyOffset = new _cesium.GeometryAttribute({
      componentDatatype: _cesium.ComponentDatatype.UNSIGNED_BYTE,
      componentsPerAttribute: 1,
      values: applyOffset
    });
  }
  return new _cesium.Geometry({
    attributes: attributes,
    indices: indices,
    primitiveType: _cesium.PrimitiveType.TRIANGLES,
    boundingSphere: boundingSphere,
    offsetAttribute: cylinderGeometry._offsetAttribute
  });
};
var unitCylinderGeometry;

/**
 * Returns the geometric representation of a unit cylinder, including its vertices, indices, and a bounding sphere.
 * @returns {Geometry} The computed vertices and indices.
 *
 * @private
 */
CylinderGeometry.getUnitCylinder = function () {
  if (!(0, _cesium.defined)(unitCylinderGeometry)) {
    unitCylinderGeometry = CylinderGeometry.createGeometry(new CylinderGeometry({
      topRadius: 1.0,
      bottomRadius: 1.0,
      length: 1.0,
      vertexFormat: _cesium.VertexFormat.POSITION_ONLY
    }));
  }
  return unitCylinderGeometry;
};
var _default = exports["default"] = CylinderGeometry;
//# sourceMappingURL=Well.js.map
