text: import {Plugin} from "../../viewer/Plugin.js";
  import {Scene} from "../../viewer/scene/scene/Scene.js";
  import {AmbientLight} from "../../viewer/scene/lights/AmbientLight.js";
  import {DirLight} from "../../viewer/scene/lights/DirLight.js";
  import {Mesh} from "../../viewer/scene/mesh/Mesh.js";
  import {ReadableGeometry} from "../../viewer/scene/geometry/ReadableGeometry.js";
  import {buildCylinderGeometry} from "../../viewer/scene/geometry/builders/buildCylinderGeometry.js";
  import {buildSphereGeometry} from "../../viewer/scene/geometry/builders/buildSphereGeometry.js";
  import {buildVectorTextGeometry} from "../../viewer/scene/geometry/builders/buildVectorTextGeometry.js";
  import {PhongMaterial} from "../../viewer/scene/materials/PhongMaterial.js";
  import {math} from "../../viewer/scene/math/math.js";
  
  /**
   * {@link Viewer} plugin that shows the axii of the World-space coordinate system.
   *
   * ## Usage
   *
   * [[Run this example](https://xeokit.github.io/xeokit-sdk/examples/#gizmos_AxisGizmoPlugin)]
   *
   * ````JavaScript````
   * import {Viewer} from "../src/viewer/Viewer.js";
   * import {GLTFLoaderPlugin} from "../src/plugins/GLTFLoaderPlugin/GLTFLoaderPlugin.js";
   * import {AxisGizmoPlugin} from "../src/plugins/AxisGizmoPlugin/AxisGizmoPlugin.js";
   *
   * const viewer = new Viewer({
   *     canvasId: "myCanvas"
   * });
   *
   * const gltfLoader = new GLTFLoaderPlugin(viewer);
   *
   * new AxisGizmoPlugin(viewer, {size: [250, 250]});
   *
   * const model = gltfLoader.load({
   *     id: "myModel",
   *     src: "./models/gltf/schependomlaan/scene.gltf",
   *     metaModelSrc: "./metaModels/schependomlaan/metaModel.json",
   *     edges: true
   * });
   *
   * const scene = viewer.scene;
   * const camera = scene.camera;
   *
   * camera.orbitPitch(20);
   *
   * model.on("loaded", () => {
   *     viewer.cameraFlight.jumpTo(modelNode);
   *     scene.on("tick", () => {
   *        camera.orbitYaw(0.4);
   *     })
   * });
   * ````
   */
  class AxisGizmoPlugin extends Plugin {
  
      /**
       * @constructor
       * @param {Viewer} viewer The Viewer.
       * @param {Object} cfg  Plugin configuration.
       * @param {String} [cfg.id="AxisGizmo"] Optional ID for this plugin, so that we can find it within {@link Viewer#plugins}.
       * @param {Number[]} [cfg.size=[250,250]] Initial size in pixels.
       */
      constructor(viewer, cfg) {
  
          cfg = cfg || {};
  
          super("AxisGizmo", viewer, cfg);
  
          var camera = viewer.scene.camera;
  
          var size = cfg.size || [250, 250];
  
          var canvas = camera.scene.canvas;
  
          // Create canvas for this gizmo
  
          var canvasId = "xeokit-axisHelper-canvas-" + math.createUUID();
          var body = document.getElementsByTagName("body")[0];
          var div = document.createElement('div');
          var style = div.style;
          style.height = size[0] + "px";
          style.width = size[1] + "px";
          style.padding = "0";
          style.margin = "0";
          style.float = "left";
          style.left = "410px";
          style.bottom = "350px";
          style.position = "absolute";
          style["z-index"] = "1000000";
          // style["background-color"] = "rgba(0,0,0,0.3)";
          div.innerHTML += '<canvas id="' + canvasId + '" style="width: ' + size[0] + 'px; height: ' + size[1] + 'px; float: left; margin: 0; padding: 0;"></canvas>';
          body.appendChild(div);
  
          canvas.on("boundary",
              function (boundary) {
                  style.left = boundary[0] + 10 + "px";
                  style.bottom = (boundary[0] + 20) + "px";
              });
  
          // The scene containing this helper
          var scene = new Scene({
              canvasId: canvasId,
              transparent: true
          });
  
          // Custom lights
          scene.clearLights();
  
          new AmbientLight(scene, {
              color: [0.45, 0.45, 0.5],
              intensity: 0.9
          });
  
          new DirLight(scene, {
              dir: [-0.5, 0.5, -0.6],
              color: [0.8, 0.8, 0.7],
              intensity: 1.0,
              space: "view"
          });
  
          new DirLight(scene, {
              dir: [0.5, -0.5, -0.6],
              color: [0.8, 0.8, 0.8],
              intensity: 1.0,
              space: "view"
          });
  
          // Rotate helper in synch with target camera
  
          var helperCamera = scene.camera;
  
          camera.on("matrix", function () {
  
              var eye = camera.eye;
              var look = camera.look;
              var up = camera.up;
  
              var eyeLook = math.mulVec3Scalar(math.normalizeVec3(math.subVec3(eye, look, [])), 22);
  
              helperCamera.look = [0, 0, 0];
              helperCamera.eye = eyeLook;
              helperCamera.up = up;
          });
  
          // ----------------- Components that are shared among more than one mesh ---------------
  
          var arrowHead = new ReadableGeometry(scene, buildCylinderGeometry({
              radiusTop: 0.01,
              radiusBottom: 0.6,
              height: 1.7,
              radialSegments: 20,
              heightSegments: 1,
              openEnded: false
          }));
  
          var arrowShaft = new ReadableGeometry(scene, buildCylinderGeometry({
              radiusTop: 0.2,
              radiusBottom: 0.2,
              height: 4.5,
              radialSegments: 20,
              heightSegments: 1,
              openEnded: false
          }));
  
          var xAxisMaterial = new PhongMaterial(scene, { // Red by convention
              diffuse: [1, 0.3, 0.3],
              ambient: [0.0, 0.0, 0.0],
              specular: [.6, .6, .3],
              shininess: 80,
              lineWidth: 2
          });
  
          var xAxisLabelMaterial = new PhongMaterial(scene, { // Red by convention
              emissive: [1, 0.3, 0.3],
              ambient: [0.0, 0.0, 0.0],
              specular: [.6, .6, .3],
              shininess: 80,
              lineWidth: 2
          });
  
          var yAxisMaterial = new PhongMaterial(scene, { // Green by convention
              diffuse: [0.3, 1, 0.3],
              ambient: [0.0, 0.0, 0.0],
              specular: [.6, .6, .3],
              shininess: 80,
              lineWidth: 2
          });
  
          var yAxisLabelMaterial = new PhongMaterial(scene, { // Green by convention
              emissive: [0.3, 1, 0.3],
              ambient: [0.0, 0.0, 0.0],
              specular: [.6, .6, .3],
              shininess: 80,
              lineWidth: 2
          });
  
  
          var zAxisMaterial = new PhongMaterial(scene, { // Blue by convention
              diffuse: [0.3, 0.3, 1],
              ambient: [0.0, 0.0, 0.0],
              specular: [.6, .6, .3],
              shininess: 80,
              lineWidth: 2
          });
  
          var zAxisLabelMaterial = new PhongMaterial(scene, {
              emissive: [0.3, 0.3, 1],
              ambient: [0.0, 0.0, 0.0],
              specular: [.6, .6, .3],
              shininess: 80,
              lineWidth: 2
          });
  
          var ballMaterial = new PhongMaterial(scene, {
              diffuse: [0.5, 0.5, 0.5],
              ambient: [0.0, 0.0, 0.0],
              specular: [.6, .6, .3],
              shininess: 80,
              lineWidth: 2
          });
  
  
          // ----------------- Meshes ------------------------------
  
          this._meshes = [
  
              // Sphere behind gnomon
  
              new Mesh(scene, {
                  geometry: new ReadableGeometry(scene, buildSphereGeometry({
                      radius: 9.0,
                      heightSegments: 60,
                      widthSegments: 60
                  })),
                  material: new PhongMaterial(scene, {
                      diffuse: [0.0, 0.0, 0.0],
                      emissive: [0.1, 0.1, 0.1],
                      ambient: [0.1, 0.1, 0.2],
                      specular: [0, 0, 0],
                      alpha: 0.4,
                      alphaMode: "blend",
                      frontface: "cw"
                  }),
                  pickable: false,
                  collidable: false,
                  visible: cfg.visible !== false
              }),
  
              // Ball at center of axis
  
              new Mesh(scene, {  // Arrow
                  geometry: new ReadableGeometry(scene, buildSphereGeometry({
                      radius: 1.0
                  })),
                  material: ballMaterial,
                  pickable: false,
                  collidable: false,
                  visible: cfg.visible !== false
              }),
  
              // X-axis arrow, shaft and label
  
              new Mesh(scene, {  // Arrow
                  geometry: arrowHead,
                  material: xAxisMaterial,
                  pickable: false,
                  collidable: false,
                  visible: cfg.visible !== false,
                  position: [-5, 0, 0],
                  rotation: [0, 0, 90]
              }),
  
              new Mesh(scene, {  // Shaft
                  geometry: arrowShaft,
                  material: xAxisMaterial,
                  pickable: false,
                  collidable: false,
                  visible: cfg.visible !== false,
                  position: [-2, 0, 0],
                  rotation: [0, 0, 90]
              }),
  
              new Mesh(scene, {  // Label
                  geometry: new ReadableGeometry(scene, buildVectorTextGeometry({text: "X", size: 1.5})),
                  material: xAxisLabelMaterial,
                  pickable: false,
                  collidable: false,
                  visible: cfg.visible !== false,
                  position: [-7, 0, 0],
                  billboard: "spherical"
              }),
  
              // Y-axis arrow, shaft and label
  
              new Mesh(scene, {  // Arrow
                  geometry: arrowHead,
                  material: yAxisMaterial,
                  pickable: false,
                  collidable: false,
                  visible: cfg.visible !== false,
                  position: [0, 5, 0]
              }),
  
              new Mesh(scene, {  // Shaft
                  geometry: arrowShaft,
                  material: yAxisMaterial,
                  pickable: false,
                  collidable: false,
                  visible: cfg.visible !== false,
                  position: [0, 2, 0]
              }),
  
              new Mesh(scene, {  // Label
                  geometry: new ReadableGeometry(scene, buildVectorTextGeometry({text: "Y", size: 1.5})),
                  material: yAxisLabelMaterial,
                  pickable: false,
                  collidable: false,
                  visible: cfg.visible !== false,
                  position: [0, 7, 0],
                  billboard: "spherical"
              }),
  
              // Z-axis arrow, shaft and label
  
              new Mesh(scene, {  // Arrow
                  geometry: arrowHead,
                  material: zAxisMaterial,
                  pickable: false,
                  collidable: false,
                  visible: cfg.visible !== false,
                  position: [0, 0, 5],
                  rotation: [90, 0, 0]
              }),
  
              new Mesh(scene, {  // Shaft
                  geometry: arrowShaft,
                  material: zAxisMaterial,
                  pickable: false,
                  collidable: false,
                  visible: cfg.visible !== false,
                  position: [0, 0, 2],
                  rotation: [90, 0, 0]
              }),
  
              new Mesh(scene, {  // Label
                  geometry: new ReadableGeometry(scene, buildVectorTextGeometry({text: "Z", size: 1.5})),
                  material: zAxisLabelMaterial,
                  pickable: false,
                  collidable: false,
                  visible: cfg.visible !== false,
                  position: [0, 0, 7],
                  billboard: "spherical"
              })
          ];
      }
  
      /** Shows or hides this helper
       *
       * @param visible
       */
      setVisible(visible) {
          for (var i = 0; i < this._meshes.length; i++) {
              this._meshes[i].visible = visible;
          }
      }
  
      /**
       * Destroys this AxisGizmoPlugin.
       */
      destroy() {
          super.destroy();
      }
  }
  
  export {AxisGizmoPlugin}