

function rotateY(point, angle) {
  const radians = angle * (Math.PI / 180);
  const cos = Math.cos(radians);
  const sin = Math.sin(radians);

  const x = point.x * cos - point.z * sin;
  const y = point.y;
  const z = point.x * sin + point.z * cos;

  return { x, y, z };
}

function rotateZ(point, angle) {
  const radians = angle * (Math.PI / 180);
  const cos = Math.cos(radians);
  const sin = Math.sin(radians);

  const x = point.x * cos - point.y * sin;
  const y = point.x * sin + point.y * cos;
  const z = point.z;

  return { x, y, z };
}


function drawCircle(count, radius, angleOffset = 0) {
  const particles = [];
  for (let i = 0; i < count; i++) {
    const angle = (i / count) * 2 * Math.PI + angleOffset;
    particles.push({
      x: Math.cos(angle) * radius,
      y: Math.sin(angle) * radius,
      z: 0
    });
  }
}


Demo.prototype.sceneTornado = function () {
  this.setScene('tornado');

  this.loader.addAnimation({
    "light": {
        "type": "Ambient",
        "properties": { "intensity": 2.0 },
        "castShadow": false
    }
    ,"color": [{
        "r": 0.8, "g": 0.8, "b": 0.8
    }]
});    

    this.loader.addAnimation({
      "light": {
          "type": "Directional",
          "properties": { "intensity": 1.5 },
          "castShadow": true
      }
      ,position:[{x:0.5,y:3,z:2}]
    });    

    const particleCount = 200;

    const emojiList = [
      {char:'🤔',count:0,array:[]},
      {char:'😢',count:0,array:[]},
      {char:'😡',count:0,array:[]},
      {char:'😍',count:0,array:[]}
    ];
    let particles = new Array(particleCount);
    for (let i = 0; i < particleCount; i++) {
      const emojiI = Utils.getRandomArrayIndex(emojiList);
      particles[i] = {
        emojiI: emojiI,
      };
      emojiList[emojiI].count++;
      emojiList[emojiI].array.push(i);
    }



    emojiList.forEach((emoji, index) => {
      const stepNewParticlesRow = 3;
      let particlesInCircle = 1;
      let rowY = 0.0;
      let rowI = 0;
      let circleStartI = 0;

      this.loader.addAnimation({
        image: emoji.char,
        position: [
          {
            x: 0,
            y: -1.2,
            z: -0.2
          }
        ],
        angle:[{             
            degreesY:()=>getSceneTimeFromStart()*60,              
            degreesZ:()=>Math.sin(getSceneTimeFromStart()*1.5)*15,      
          }],
        /*angle: [{
          degreesY: ()=> getSceneTimeFromStart() * 60,
          degreesX: ()=> getSceneTimeFromStart() * 60
      }],*/
        scale: [{ uniform3d: 1.0 }],
        "perspective": "3d",
        "billboard": true,
        "additive": true,
        /*"material":{
          "blending": 'AdditiveBlending',
          "transparent":true,
          "depthWrite":false,
        },*/
        color: [{r:1,g:1,b:1}],
        //"scale":[{"uniform3d":.1}],
        "instancer": {
          "count": emoji.count,
          "runInstanceFunction": (properties) => {


            const i = emoji.array[properties.index];
            const count = properties.count;
            const time = properties.time;
            let object = properties.object;
            let color = properties.color;

            if (properties.index == 0) {
              particlesInCircle = 3;
              rowY = 0.0;
              circleStartI = 0;
              rowI = 0;
            }

            let scale = 1.0;//particleSize*particle.scale*((Math.sin(getSceneTimeFromStart()*4.0+particle.x+particle.y+particle.z)*0.5+0.5)*0.5+0.5);

            let startPercent = Math.min(time/24.0,1.0);
            const fadeStart = 0.9;
            let alpha = 1.0;
            if (startPercent < (1.0-fadeStart)) {
              alpha = Math.min(startPercent / (1.0-fadeStart), 1.0);
            } else if (startPercent > fadeStart) {
              alpha = Math.max(1.0-((startPercent-fadeStart) / (1.0-fadeStart)),0.0);
            }
              scale *= alpha;
 
            /*if (particles[i].emojiI === index) {
              color.a = 0.0;
              scale = 0.0;
              object.scale.x = scale;
              object.scale.y = scale;
              object.scale.z = scale;
              return;
            }*/

            const minRadius = 0.0;
            const maxRadius = 2.0;
            const minY = 0.0;
            const maxY = 1.5;
            const stepY = 0.2;
            const rows = 10;

            if ((i-circleStartI) >= particlesInCircle) {
              particlesInCircle += stepNewParticlesRow;
              rowY += stepY;
              circleStartI = i;
              rowI++;
            };

                      const bpm = 160;
          const beat = 60/bpm;

          let evenBeat = (2.0*getSceneTimeFromStart());
          if (evenBeat%(beat*4) < beat*2) {
            evenBeat = 0.0;
          }
          evenBeat *= 0.5;
          if (time < beat*15 || time > beat*44) {
            evenBeat = 0.0;
          }

            let dirY = rowI%2==0? 5:-1+evenBeat;

            if (time> beat*48) {
              dirY*=(time-(beat*48))*((time-(beat*48))/8);
            }

            const percent = (i-circleStartI) / particlesInCircle;
            const angle = (percent) * 2 * Math.PI;
            const radius = 0.2+rowY*0.7;//percent * (maxRadius - minRadius) + minRadius;
            //const y = (Math.floor(i / rows)+1) * stepY;
            const move = Math.sin(getSceneTimeFromStart()*2.0+rowY)*0.1;
            const particle = rotateY({
              x: Math.cos(angle) * radius + move,
              y: rowY,
              z: Math.sin(angle) * radius + move,
            }, dirY*getSceneTimeFromStart()*20.5);


            object.position.x = particle.x;
            object.position.y = particle.y;
            object.position.z = particle.z;


              color.r = 1.0;
              color.g = 1.0;
              color.b = 0.0;
              color.a = alpha;
            //}

            object.scale.x = scale;
            object.scale.y = scale;
            object.scale.z = scale;
          }
        }
      });
      });
 //};

}