const Universe = function () {
  const size = TDEMO.MAIN.getRendererSize();
  PartBase.call(this, {
    camera: new THREE.OrthographicCamera(
      -size[0] / 2,
      size[0] / 2,
      size[1] / 2,
      -size[1] / 2,
      0.1,
      2000
    ),
  });
  this.camera.position.z = 1;

  this.mainScene = new THREE.Scene();
  const aspect = this.width / this.height;
  this.mainCamera = new THREE.PerspectiveCamera(
    60,
    aspect,
    this.near,
    100
  );
  this.mainScene.add(this.mainCamera);

  this.rtt = new THREE.WebGLRenderTarget(size[0], size[1]);
  this.rtt.texture.format = THREE.RGBFormat;
  this.rtt.texture.minFilter = THREE.NearestFilter;
  this.rtt.texture.magFilter = THREE.NearestFilter;
  this.rtt.texture.generateMipmaps = false;
  this.rtt.stencilBuffer = false;

  this.uniforms = THREE.Universe.uniforms;
  this.uniforms.uNear.value = this.near;
  this.uniforms.uFar.value = this.far;
  this.uniforms.uResolution.value = size;

  const pg = new THREE.PlaneBufferGeometry(this.width, this.height);
  const pm = new THREE.ShaderMaterial({
    uniforms: this.uniforms,
    vertexShader: THREE.Universe.vertexShader,
    fragmentShader: THREE.Universe.fragmentShader,
  });

  this.plane = new THREE.Mesh(pg, pm);
  this.scene.add(this.plane);

  //POSTPROCESSING
  this.setEdgeDetection();
  this.setBloom(1.);

};

Universe.prototype = PartBase.prototype.inheritance();

Universe.prototype.animateCamera = function () {
  this.near = TDEMO.SYNC.getNear();
  this.far = TDEMO.SYNC.getFar();

  this.mainCamera.near = this.near;
  this.mainCamera.far = this.far;
  this.lens = TDEMO.SYNC.getLens();
  this.mainCamera.filmGauge = this.lens.fg;
  this.mainCamera.setFocalLength(this.lens.fl);
  this.mainCamera.updateProjectionMatrix();

  const camp = TDEMO.SYNC.getCameraPosition();
  this.mainCamera.position.x = camp.x;
  this.mainCamera.position.y = camp.y;
  this.mainCamera.position.z = camp.z;

  const camr = TDEMO.SYNC.getCameraRotation();
  this.mainCamera.lookAt(camr);

  this.uniforms.uNear.value = this.near;
  this.uniforms.uFar.value = this.far;
  this.uniforms.uRo.value = camp;
  this.uniforms.uRd.value = camr;
  this.uniforms.uFOV.value = this.mainCamera.getEffectiveFOV();
};

Universe.prototype.animate = function (elapsedTime, delta) {
  PartBase.prototype.animate.call(this, elapsedTime, delta, false);
  this.animateCamera();
  const hb = TDEMO.SYNC.getHeartBeat();
  this.uniforms.uHb.value = hb;
  this.uniforms.uTime.value = elapsedTime;

  const edges = TDEMO.SYNC.getEdges();
  this.edge.enabled = edges;
};
