
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 };
}


Demo.prototype.sceneMorph = function ()
{
  this.loader.setScene('morph'); 
  //this.loader.addAnimation({fbo:{name:'elite',action:'begin',storeDepth:false}});
  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}]
    });    

  let startTime = 0;
  let durationTime = 40;
  let particleSize = 1.0;
  let parentId = null;

  const meshVertexCount = Math.floor(5382/10)+1;
  let particles = new Array(meshVertexCount);
  let particles2 = new Array(meshVertexCount);
  const deg2rad = 0.01745329251;
  const localCamPos = [0.0, 0.0, 0.0];
  const localCamDir = [0.0, 0.0, 0.1];
  const camFov = 75.0 * deg2rad;
  /*this.loader.addAnimation({
    image: ['_embedded/defaultWhite.png'],
    perspective: '3d',
    position:[{"x":0.0,"y":0.0,"z":1.0}],
    scale: [{ uniform2d: 1.0}],

    "material":{
      depthTest: false,
      depthWrite: false,
      blending: 'NormalBlending'
    },
    "shader":{
      "name":["multiSceneEffects/rayMarcher.vs","multiSceneEffects/rayMarcher.fs"],
      "variable":
      [          
        {"name":"MAX_STEPS","type":"float","value":[45.0]},
        {"name":"MAX_DIST","type":"float","value":[30.0]},
        {"name":"inCamPos","type":"vec3","value":[localCamPos]},
        {"name":"camDirection","type":"vec3","value":[localCamDir]},
        {"name":"camNear","type":"mat4","value":[.05]},
        {"name":"camFar","type":"mat4","value":[100]},
        {"name":"camFov","type":"mat4","value":[camFov]},
        {"name":"effectType","type":"int","value":[2]}
      ]
    }
});*/

{
                        const bpm = 160;
          const beat = 60/bpm;
          const emojiList = ['😂', '😃', '😎', '🤔', '😢', '😡', '😍', '🥳', '🤯', '😴'];

          for (let i = 0; i < 100; i++) {
            this.loader.addAnimation({
              start:beat*20+beat*Math.floor(50*Utils.random()),
              duration:beat,
            image: Utils.getRandomArrayElement(emojiList),
            scale: [{ uniform2d: Utils.random()*1.5+0.5 }],
            position: [{ x: Utils.random()*0.8 - 0.4, y: Utils.random()*0.8 - 0.4, }],
            color:[{a:1.0}]
            });
          }

}
  this.loader.addAnimation(
    {
      end:-1,
      object: {
        name: 'emoji_laugh.obj'
      },
      position: [
        {
          x: 0.0,
          y: 0.0,
          z: 0
        }
      ],
      //scale: [{ uniform3d: 2.8 }],
      objectOnLoadFunction:(meshData) => {
        if (!meshData.mesh[0].position) {
          throw new Error("Mesh position not found");
        }
        if (meshVertexCount != meshData.mesh[0].position.count/3) {
          //throw new Error(`Mesh vertex count mismatch (expected ${meshVertexCount}, got ${meshData.mesh[0].position.count/3})`);
        }

        for (let i = 0,j=0; i < particles.length; i++,j+=10) {
          const x = meshData.mesh[0].position.array[j*3+0];
          const y = meshData.mesh[0].position.array[j*3+1];
          const z = meshData.mesh[0].position.array[j*3+2];
          const scatter = 0.04;
          particles[i] = {
            "x": x,//+Utils.random()*scatter-scatter/2.0,
            "y": y,//+Utils.random()*scatter-scatter/2.0,
            "z": z,//+Utils.random()*scatter-scatter/2.0,
            "scale": 1.0,//Utils.random()*0.7+0.3,
          };
        }
      }
      //color: [{r:.45,g:.0,b:.0}],
    }
  );

  this.loader.addAnimation(
    {
      end:-1,
      object: {
        name: 'jml_fist.obj'
      },
      position: [
        {
          x: 0.0,
          y: 0.0,
          z: 0
        }
      ],
      //scale: [{ uniform3d: 2.8 }],
      objectOnLoadFunction:(meshData) => {
        if (!meshData.mesh[0].position) {
          throw new Error("Mesh position not found");
        }
        if (meshVertexCount != meshData.mesh[0].position.count/3) {
          //throw new Error(`Mesh vertex count mismatch (expected ${meshVertexCount}, got ${meshData.mesh[0].position.count/3})`);
        }

        for (let i = 0,j=0; i < particles2.length; i++,j+=10) {
          const x = meshData.mesh[0].position.array[j*3+0];
          const y = meshData.mesh[0].position.array[j*3+1];
          const z = meshData.mesh[0].position.array[j*3+2];
          const scatter = 0.04;
          particles2[i] = {
            "x": x,//+Utils.random()*scatter-scatter/2.0,
            "y": y,//+Utils.random()*scatter-scatter/2.0,
            "z": z,//+Utils.random()*scatter-scatter/2.0,
            "scale": 1.0,//Utils.random()*0.7+0.3,
          };
        }
      }
      //color: [{r:.45,g:.0,b:.0}],
    }
  );


  let numberList = [2,9,0,8,2,5];

  //const particleNumbers = (num) => {
    const particleCount = particles.length;// / numberList.length;
    this.loader.addAnimation({
      "start":startTime, "duration":durationTime,
      //"image": 'images/bitfont_'+numberList[num]+'.png',
      image: '😍',
      //image: 'images/bitfont_0.png',
      textureProperties: [{},{minFilter: 'NearestMipmapNearestFilter', magFilter: 'LinearFilter'}],
      "parent":parentId,
      position: [
        {
          x: 0.0,
          y: -.1,
          z: 0
        }
      ],
      /*angle:[{             
          //degreesY:()=>getSceneTimeFromStart()*60,              
          degreesZ:()=>Math.sin(getSceneTimeFromStart()*1.5)*15,      
        }],*/
      angle: [{
        degreesY: ()=> getSceneTimeFromStart() * 60,
        degreesX: ()=> getSceneTimeFromStart() * 60
     }],
      
      "perspective": "3d",
      "billboard": true,
      "additive": false,
      "material":{
        "blending": 'AdditiveBlending',
        "transparent":true,
        "depthWrite":false,

      },
      color: [{r:0.7,g:0.7,b:0.7}],
      scale: [{
        uniform3d: ()=> 1.5 + Math.sin(getSceneTimeFromStart() * 10.5) * 0.2
      },{duration:10.5},{
        duration:1.0,uniform3d: ()=> 0.2 + Math.sin(getSceneTimeFromStart() * 10.5) * 0.02
      }],
      "instancer": {
        "count": particleCount,
        "runInstanceFunction": (properties) => {

          const i = properties.index;
          const count = properties.count;
          const time = properties.time;
          let object = properties.object;
          let color = properties.color;

          const particle = particles[i]; //particles[(i*(num+1))%particleCount];

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

          const percent = time/21.0;

          let startPercent = Math.min(time/10.0,1.0);
          if (i > startPercent*count) {
            scale = 0.0;
          }
          scale *= startPercent;

          if (percent > 0.5) {
            const particle2 = particles2[i];

            let deltaPercent = 0;
            if (percent > 0.5 && percent < 0.7) {
              deltaPercent = Math.min((percent - 0.5) / 0.2, 1.0);
            } else if (percent >= 0.7) {
              deltaPercent = 1.0;
            }
            let deltaX = particle2.x*deltaPercent - particle.x*(1.0-deltaPercent);
            let deltaY = particle2.y*deltaPercent - particle.y*(1.0-deltaPercent);
            let deltaZ = particle2.z*deltaPercent - particle.z*(1.0-deltaPercent);

            object.position.x = deltaX;
            object.position.y = deltaY;
            object.position.z = deltaZ;

            //scale *= 0.5 + Math.sin(getSceneTimeFromStart() * 10.5) * 0.02;
          }


          /*const rotatedPosition = rotateY(particle, -getSceneTimeFromStart()*40);
          object.position.x = rotatedPosition.x;
          object.position.y = rotatedPosition.y;
          object.position.z = rotatedPosition.z;*/

          /*if (object.position.x > -0.6 && object.position.x < -0.0 && object.position.z > 0.0) {
            let xAsPercent = Math.abs(object.position.x+0.0)/0.6;
            xAsPercent = xAsPercent < 0.5 ? xAsPercent * 2.0 : xAsPercent * 2.0 - 1.0;

            scale *= 2.5*(xAsPercent);
            color.r = 1.0;
            color.g = 1.0;
            color.b = xAsPercent;
          } else {*/
            color.r = 1.0;
            color.g = 1.0;
            color.b = 0.0;
          //}

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

//  this.loader.addAnimation({fbo:{name:'elite',action:'unbind'}});
}
