var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
  return value;
};
import { Group, Color, SphereGeometry, PointsMaterial, Points, ShaderMaterial, Mesh, SpriteMaterial, Sprite, NormalBlending, MeshBasicMaterial, DoubleSide } from "../../../../../../../../node_modules/.pnpm/three@0.145.0/node_modules/three/build/three.module.mjs";
import { createPointMesh, createLightPillar, createWaveMesh, getCirclePoints, createAnimateLine } from "../Utils/common.mjs";
import { gsap as gsapWithCSS } from "../../../../../../../../node_modules/.pnpm/gsap@3.12.2/node_modules/gsap/index.mjs";
import { flyArc } from "../Utils/arc.mjs";
import earthVertex from "../shaders/earth/vertex.vs.mjs";
import earthFragment from "../shaders/earth/fragment.fs.mjs";
class earth {
  constructor(options) {
    __publicField(this, "group");
    __publicField(this, "earthGroup");
    __publicField(this, "around");
    __publicField(this, "aroundPoints");
    __publicField(this, "options");
    __publicField(this, "uniforms");
    __publicField(this, "timeValue");
    __publicField(this, "earth");
    __publicField(this, "punctuationMaterial");
    __publicField(this, "markupPoint");
    __publicField(this, "waveMeshArr");
    __publicField(this, "circleLineList");
    __publicField(this, "circleList");
    __publicField(this, "x");
    __publicField(this, "n");
    __publicField(this, "isRotation");
    __publicField(this, "flyLineArcGroup");
    this.options = options;
    this.group = new Group();
    this.group.name = "group";
    this.group.scale.set(0, 0, 0);
    this.earthGroup = new Group();
    this.group.add(this.earthGroup);
    this.earthGroup.name = "EarthGroup";
    this.markupPoint = new Group();
    this.markupPoint.name = "markupPoint";
    this.waveMeshArr = [];
    this.circleLineList = [];
    this.circleList = [];
    this.x = 0;
    this.n = 0;
    this.isRotation = this.options.earth.isRotation;
    this.timeValue = 200;
    this.uniforms = {
      glowColor: {
        value: new Color(840171)
      },
      scale: {
        type: "f",
        value: -1
      },
      bias: {
        type: "f",
        value: 1
      },
      power: {
        type: "f",
        value: 3.3
      },
      time: {
        type: "f",
        value: this.timeValue
      },
      isHover: {
        value: false
      },
      map: {
        value: void 0
      }
    };
  }
  async init() {
    return new Promise((resolve) => {
      const init = async () => {
        this.createEarth();
        this.createEarthGlow();
        this.createEarthAperture();
        await this.createMarkupPoint();
        this.createAnimateCircle();
        this.createFlyLine();
        this.show();
        resolve();
      };
      init();
    });
  }
  createEarth() {
    const earth_geometry = new SphereGeometry(this.options.earth.radius, 50, 50);
    const earth_border = new SphereGeometry(this.options.earth.radius + 10, 60, 60);
    const pointMaterial = new PointsMaterial({
      color: 8519679,
      //设置颜色，默认 0xFFFFFF
      transparent: true,
      sizeAttenuation: true,
      opacity: 0.1,
      vertexColors: false,
      //定义材料是否使用顶点颜色，默认false ---如果该选项设置为true，则color属性失效
      size: 0.2
      //定义粒子的大小。默认为1.0
    });
    const points = new Points(earth_border, pointMaterial);
    this.earthGroup.add(points);
    this.uniforms.map.value = this.options.textures.earth;
    const earth_material = new ShaderMaterial({
      // wireframe:true, // 显示模型线条
      uniforms: this.uniforms,
      vertexShader: earthVertex,
      fragmentShader: earthFragment
    });
    earth_material.needsUpdate = true;
    this.earth = new Mesh(earth_geometry, earth_material);
    this.earth.name = "earth";
    this.earthGroup.add(this.earth);
  }
  createEarthGlow() {
    const R = this.options.earth.radius;
    const texture = this.options.textures.glow;
    const spriteMaterial = new SpriteMaterial({
      map: texture,
      // 设置精灵纹理贴图
      color: 4427985,
      transparent: true,
      //开启透明
      opacity: 0.7,
      // 可以通过透明度整体调节光圈
      depthWrite: false
      //禁止写入深度缓冲区数据
    });
    const sprite = new Sprite(spriteMaterial);
    sprite.scale.set(R * 3, R * 3, 1);
    this.earthGroup.add(sprite);
  }
  createEarthAperture() {
    const vertexShader = [
      "varying vec3	vVertexWorldPosition;",
      "varying vec3	vVertexNormal;",
      "varying vec4	vFragColor;",
      "void main(){",
      "	vVertexNormal	= normalize(normalMatrix * normal);",
      //将法线转换到视图坐标系中
      "	vVertexWorldPosition	= (modelMatrix * vec4(position, 1.0)).xyz;",
      //将顶点转换到世界坐标系中
      "	// set gl_Position",
      "	gl_Position	= projectionMatrix * modelViewMatrix * vec4(position, 1.0);",
      "}"
    ].join("\n");
    const AeroSphere = {
      uniforms: {
        coeficient: {
          type: "f",
          value: 1
        },
        power: {
          type: "f",
          value: 3
        },
        glowColor: {
          type: "c",
          value: new Color(4427985)
        }
      },
      vertexShader,
      fragmentShader: [
        "uniform vec3	glowColor;",
        "uniform float	coeficient;",
        "uniform float	power;",
        "varying vec3	vVertexNormal;",
        "varying vec3	vVertexWorldPosition;",
        "varying vec4	vFragColor;",
        "void main(){",
        "	vec3 worldCameraToVertex = vVertexWorldPosition - cameraPosition;",
        //世界坐标系中从相机位置到顶点位置的距离
        "	vec3 viewCameraToVertex	= (viewMatrix * vec4(worldCameraToVertex, 0.0)).xyz;",
        //视图坐标系中从相机位置到顶点位置的距离
        "	viewCameraToVertex= normalize(viewCameraToVertex);",
        //规一化
        "	float intensity	= pow(coeficient + dot(vVertexNormal, viewCameraToVertex), power);",
        "	gl_FragColor = vec4(glowColor, intensity);",
        "}"
      ].join("\n")
    };
    const material1 = new ShaderMaterial({
      uniforms: AeroSphere.uniforms,
      vertexShader: AeroSphere.vertexShader,
      fragmentShader: AeroSphere.fragmentShader,
      blending: NormalBlending,
      transparent: true,
      depthWrite: false
    });
    const sphere = new SphereGeometry(this.options.earth.radius + 0, 50, 50);
    const mesh = new Mesh(sphere, material1);
    this.earthGroup.add(mesh);
  }
  async createMarkupPoint() {
    await Promise.all(
      this.options.data.map(async (item) => {
        const radius = this.options.earth.radius;
        const lon = item.startArray.E;
        const lat = item.startArray.N;
        this.punctuationMaterial = new MeshBasicMaterial({
          color: this.options.punctuation.circleColor,
          map: this.options.textures.label,
          transparent: true,
          //使用背景透明的png贴图，注意开启透明计算
          depthWrite: false
          //禁止写入深度缓冲区数据
        });
        const mesh = createPointMesh({ radius, lon, lat, material: this.punctuationMaterial });
        this.markupPoint.add(mesh);
        const LightPillar = createLightPillar({
          radius: this.options.earth.radius,
          lon,
          lat,
          index: 0,
          textures: this.options.textures,
          punctuation: this.options.punctuation
        });
        this.markupPoint.add(LightPillar);
        const WaveMesh = createWaveMesh({ radius, lon, lat, textures: this.options.textures });
        this.markupPoint.add(WaveMesh);
        this.waveMeshArr.push(WaveMesh);
        await Promise.all(
          item.endArray.map((obj) => {
            const lon2 = obj.E;
            const lat2 = obj.N;
            const mesh2 = createPointMesh({ radius, lon: lon2, lat: lat2, material: this.punctuationMaterial });
            this.markupPoint.add(mesh2);
            const LightPillar2 = createLightPillar({
              radius: this.options.earth.radius,
              lon: lon2,
              lat: lat2,
              index: 1,
              textures: this.options.textures,
              punctuation: this.options.punctuation
            });
            this.markupPoint.add(LightPillar2);
            const WaveMesh2 = createWaveMesh({ radius, lon: lon2, lat: lat2, textures: this.options.textures });
            this.markupPoint.add(WaveMesh2);
            this.waveMeshArr.push(WaveMesh2);
          })
        );
        this.earthGroup.add(this.markupPoint);
      })
    );
  }
  createAnimateCircle() {
    const list = getCirclePoints({
      radius: this.options.earth.radius + 15,
      number: 150,
      //切割数
      closed: true
      // 闭合
    });
    const mat = new MeshBasicMaterial({
      color: "#0c3172",
      transparent: true,
      opacity: 0.4,
      side: DoubleSide
    });
    const line = createAnimateLine({
      pointList: list,
      material: mat,
      number: 100,
      radius: 0.1
    });
    this.earthGroup.add(line);
    const l2 = line.clone();
    l2.scale.set(1.2, 1.2, 1.2);
    l2.rotateZ(Math.PI / 6);
    this.earthGroup.add(l2);
    const l3 = line.clone();
    l3.scale.set(0.8, 0.8, 0.8);
    l3.rotateZ(-Math.PI / 6);
    this.earthGroup.add(l3);
    const ball = new Mesh(
      new SphereGeometry(this.options.satellite.size, 32, 32),
      new MeshBasicMaterial({
        color: "#e0b187"
        // 745F4D
      })
    );
    const ball2 = new Mesh(
      new SphereGeometry(this.options.satellite.size, 32, 32),
      new MeshBasicMaterial({
        color: "#628fbb"
        // 324A62
      })
    );
    const ball3 = new Mesh(
      new SphereGeometry(this.options.satellite.size, 32, 32),
      new MeshBasicMaterial({
        color: "#806bdf"
        //6D5AC4
      })
    );
    this.circleLineList.push(line, l2, l3);
    ball.name = ball2.name = ball3.name = "卫星";
    for (let i = 0; i < this.options.satellite.number; i++) {
      const ball01 = ball.clone();
      const num = Math.floor(list.length / this.options.satellite.number);
      ball01.position.set(list[num * (i + 1)][0] * 1, list[num * (i + 1)][1] * 1, list[num * (i + 1)][2] * 1);
      line.add(ball01);
      const ball02 = ball2.clone();
      const num02 = Math.floor(list.length / this.options.satellite.number);
      ball02.position.set(list[num02 * (i + 1)][0] * 1, list[num02 * (i + 1)][1] * 1, list[num02 * (i + 1)][2] * 1);
      l2.add(ball02);
      const ball03 = ball2.clone();
      const num03 = Math.floor(list.length / this.options.satellite.number);
      ball03.position.set(list[num03 * (i + 1)][0] * 1, list[num03 * (i + 1)][1] * 1, list[num03 * (i + 1)][2] * 1);
      l3.add(ball03);
    }
  }
  createFlyLine() {
    this.flyLineArcGroup = new Group();
    this.flyLineArcGroup.userData["flyLineArray"] = [];
    this.earthGroup.add(this.flyLineArcGroup);
    this.options.data.forEach((cities) => {
      cities.endArray.forEach((item) => {
        const arcline = flyArc(
          this.options.earth.radius,
          cities.startArray.E,
          cities.startArray.N,
          item.E,
          item.N,
          this.options.flyLine
        );
        this.flyLineArcGroup.add(arcline);
        this.flyLineArcGroup.userData["flyLineArray"].push(arcline.userData["flyLine"]);
      });
    });
  }
  show() {
    gsapWithCSS.to(this.group.scale, {
      x: 1,
      y: 1,
      z: 1,
      duration: 2,
      ease: "Quadratic"
    });
  }
  render() {
    var _a, _b;
    (_b = (_a = this.flyLineArcGroup) == null ? void 0 : _a.userData["flyLineArray"]) == null ? void 0 : _b.forEach((fly) => {
      fly.rotation.z += this.options.flyLine.speed;
      if (fly.rotation.z >= fly.flyEndAngle)
        fly.rotation.z = 0;
    });
    if (this.isRotation) {
      this.earthGroup.rotation.y += this.options.earth.rotateSpeed;
    }
    this.circleLineList.forEach((e) => {
      e.rotateY(this.options.satellite.rotateSpeed);
    });
    this.uniforms.time.value = this.uniforms.time.value < -this.timeValue ? this.timeValue : this.uniforms.time.value - 1;
    if (this.waveMeshArr.length) {
      this.waveMeshArr.forEach((mesh) => {
        mesh.userData["scale"] += 7e-3;
        mesh.scale.set(
          mesh.userData["size"] * mesh.userData["scale"],
          mesh.userData["size"] * mesh.userData["scale"],
          mesh.userData["size"] * mesh.userData["scale"]
        );
        if (mesh.userData["scale"] <= 1.5) {
          mesh.material.opacity = (mesh.userData["scale"] - 1) * 2;
        } else if (mesh.userData["scale"] > 1.5 && mesh.userData["scale"] <= 2) {
          mesh.material.opacity = 1 - (mesh.userData["scale"] - 1.5) * 2;
        } else {
          mesh.userData["scale"] = 1;
        }
      });
    }
  }
}
export {
  earth as default
};
