const canvas = document.getElementById("renderCanvas");
const engine = new BABYLON.Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true, disableWebGL2Support: false });
var curX = -5;
var resti = 0.01
var fric = 0.9
var movingMass = 0.01

var endToggle = false
let segments = 9
let maxDist = segments+1.5
let minDist = 3
let pillispeed = 0.1
let twigparts = []
let deletetwig = []
let shadowGenerator
let bodycam

let pilliBaseColor = 'hsl('+BABYLON.Scalar.RandomRange(0,360)+', 70%, 50%)'
let pilliSecondColor = BABYLON.Color3.Random()
let pilliPatternWidth = BABYLON.Scalar.RandomRange(10,400)
let pilli
var curve
var pipeline
var wiggleAnim
let bodycamAnim
let bodyCamRotationSpeed = 0.1
let lastwalk = 0
let congaPart
let bellPart

const bell = new Tone.MembraneSynth().toDestination();
let part1, part2

/*const conga = new Tone.MembraneSynth({
        pitchDecay: 0.008,
        octaves: 2,
        envelope: {
            attack: 0.0006,
            decay: 0.5,
            sustain: 0
        }
    }).toDestination();
*/







function music(){

    let notes2 = [
        {
          "duration": 0.25,
          "durationTicks": 192,
          "midi": 70,
          "name": "A#4",
          "ticks": 0,
          "time": 0,
          "velocity": 0.3937007874015748
        },
        {
          "duration": 0.125,
          "durationTicks": 96,
          "midi": 58,
          "name": "A#3",
          "ticks": 192,
          "time": 0.25,
          "velocity": 0.3937007874015748
        },
        {
          "duration": 0.125,
          "durationTicks": 96,
          "midi": 63,
          "name": "D#4",
          "ticks": 288,
          "time": 0.375,
          "velocity": 0.3937007874015748
        },
        {
          "duration": 0.125,
          "durationTicks": 96,
          "midi": 58,
          "name": "A#3",
          "ticks": 2016,
          "time": 2.625,
          "velocity": 0.3937007874015748
        },
        {
          "duration": 0.25,
          "durationTicks": 192,
          "midi": 70,
          "name": "A#4",
          "ticks": 2304,
          "time": 3,
          "velocity": 0.3937007874015748
        },
        {
          "duration": 0.125,
          "durationTicks": 96,
          "midi": 58,
          "name": "A#3",
          "ticks": 2496,
          "time": 3.25,
          "velocity": 0.3937007874015748
        },
        {
          "duration": 0.125,
          "durationTicks": 96,
          "midi": 63,
          "name": "D#4",
          "ticks": 2592,
          "time": 3.375,
          "velocity": 0.3937007874015748
        },
        {
          "duration": 0.125,
          "durationTicks": 96,
          "midi": 58,
          "name": "A#3",
          "ticks": 4320,
          "time": 5.625,
          "velocity": 0.3937007874015748
        }
      ]


      let notes = [
        {
          "duration": 0.125,
          "durationTicks": 96,
          "midi": 53,
          "name": "F3",
          "ticks": 480,
          "time": 0.625,
          "velocity": 0.3937007874015748
        },
        {
          "duration": 0.125,
          "durationTicks": 96,
          "midi": 55,
          "name": "G3",
          "ticks": 768,
          "time": 1,
          "velocity": 0.3937007874015748
        },
        {
          "duration": 0.25,
          "durationTicks": 192,
          "midi": 56,
          "name": "G#3",
          "ticks": 1152,
          "time": 1.5,
          "velocity": 0.3937007874015748
        },
        {
          "duration": 0.125,
          "durationTicks": 96,
          "midi": 55,
          "name": "G3",
          "ticks": 1440,
          "time": 1.875,
          "velocity": 0.3937007874015748
        },
        {
          "duration": 0.125,
          "durationTicks": 96,
          "midi": 53,
          "name": "F3",
          "ticks": 1728,
          "time": 2.25,
          "velocity": 0.3937007874015748
        },
        {
          "duration": 0.125,
          "durationTicks": 96,
          "midi": 53,
          "name": "F3",
          "ticks": 2784,
          "time": 3.625,
          "velocity": 0.3937007874015748
        },
        {
          "duration": 0.125,
          "durationTicks": 96,
          "midi": 55,
          "name": "G3",
          "ticks": 3072,
          "time": 4,
          "velocity": 0.3937007874015748
        },
        {
          "duration": 0.25,
          "durationTicks": 192,
          "midi": 56,
          "name": "G#3",
          "ticks": 3456,
          "time": 4.5,
          "velocity": 0.3937007874015748
        },
        {
          "duration": 0.125,
          "durationTicks": 96,
          "midi": 55,
          "name": "G3",
          "ticks": 3744,
          "time": 4.875,
          "velocity": 0.3937007874015748
        },
        {
          "duration": 0.125,
          "durationTicks": 96,
          "midi": 53,
          "name": "F3",
          "ticks": 4032,
          "time": 5.25,
          "velocity": 0.3937007874015748
        }
      ]

       part = new Tone.Part(((time, note) => {
			bell.triggerAttackRelease(note.name, note.duration, time, note.velocity);
		}), notes).start(0);

        part2 = new Tone.Part(((time, note) => {
			bell.triggerAttackRelease(note.name, note.duration, time, note.velocity);
		}), notes2).start(0);

		part.loop = true;
		part.loopEnd = "3m";

        part2.loop = true;
		part2.loopEnd = "3m";

		Tone.Transport.bpm.value = 120;

        Tone.Transport.start()
        part2.mute = true

}

function makeShield(t1, t2){
    var ground = BABYLON.MeshBuilder.CreateGround("ground1", {width: 10, height: 2.5, subdivisions: 25});

    var textureResolution = 512;
	var textureGround = new BABYLON.DynamicTexture("dynamic texture", {width:512, height:256});
	var textureContext = textureGround.getContext();

    //textureGround.clear();
    //textureGround.getContext().clearRect(0,0,512,512);
    //textureGround.update();

	var materialGround = new BABYLON.StandardMaterial("Mat");
	materialGround.diffuseTexture = textureGround;
    materialGround.diffuseTexture.hasAlpha = true;
    ground.material = materialGround;
    //Add text to dynamic texture
    var font = "bold 64px monospace";
    textureGround.drawText(t1, 75, 135, font, "white", "transparent", true, true);
    textureGround.drawText(t2, 75, 215, font, "white", "transparent", true, true);


    ground.position.y += 10
    ground.position.x = -twigparts[0].position.x
    ground.rotation.x = Math.PI*1.5
    ground.rotation.y = Math.PI

    ground.parent = twigparts[0]
    return ground

}

function makeShield2(t1, t2){
    var ground = BABYLON.MeshBuilder.CreateGround("ground3", {width: 10, height: 2.5, subdivisions: 25});

    var textureResolution = 512;
	var textureGround = new BABYLON.DynamicTexture("dynamic texture", {width:512, height:256});
	var textureContext = textureGround.getContext();

    //textureGround.clear();
    //textureGround.getContext().clearRect(0,0,512,512);
    //textureGround.update();

	var materialGround = new BABYLON.StandardMaterial("Mat");
	materialGround.diffuseTexture = textureGround;
    materialGround.diffuseTexture.hasAlpha = true;
    ground.material = materialGround;
    //Add text to dynamic texture
    var font = "bold 64px monospace";
    textureGround.drawText(t1, 1, 135, font, "white", "transparent", true, true);
    textureGround.drawText(t2, 1, 215, font, "white", "transparent", true, true);


    ground.position.y += 10
    ground.position.x = -twigparts[0].position.x
    ground.rotation.x = Math.PI*1.5
    ground.rotation.y = Math.PI
    ground.rotation.z = Math.PI

    ground.parent = twigparts[0]
    console.log("SHIELD@")

}

function addWoodMaterial(mesh) {
    //mesh.material = new BABYLON.StandardMaterial("mat" + mesh.name);



	let texSize = 512;
    let dynTex = new BABYLON.DynamicTexture("decalTex", {width: texSize, height: texSize});
    let context = dynTex.getContext();

	context.fillStyle = "#4d401e";
	context.fillRect(0, 0, texSize, texSize);



    var pbr = new BABYLON.PBRMetallicRoughnessMaterial("pbr");
    mesh.material = pbr;
    mesh.material.baseTexture = dynTex;

    //pbr.baseColor = new BABYLON.Color3(1.0, 0.766, 0.336);
    pbr.metallic = 0.5;
    pbr.roughness = 0.5;


	dynTex.update();

    mesh.receiveShadows = true;


}

function addMat(mesh, scene) {

	let texSize = 512;
    let dynTex = new BABYLON.DynamicTexture("decalTex", {width: texSize, height: texSize}, scene);
    let context = dynTex.getContext();

	context.fillStyle = pilliBaseColor;
	context.fillRect(0, 0, texSize, texSize);
	context.fillStyle = pilliSecondColor.toHexString();
	context.fillRect(texSize/2-pilliPatternWidth/2, BABYLON.Scalar.RandomRange(0,texSize/2), texSize/2+pilliPatternWidth/2, BABYLON.Scalar.RandomRange(texSize/2, texSize));

    var pbr = new BABYLON.PBRMetallicRoughnessMaterial("pbr");
    mesh.material = pbr;
    mesh.material.baseTexture = dynTex;

    //pbr.baseColor = new BABYLON.Color3(1.0, 0.766, 0.336);
    pbr.metallic = 0.5;
    pbr.roughness = 0.5;

	dynTex.update();


}

function makeFluff(double, len){

	const points1 = []
    for(let i = 0; i<400; i++){
		var x1;
        var x2;
        while(true){
            x1 = Math.random();
            x2 = Math.random();
            x1=2*(x1-0.5)
            x2=2*(x2-0.5)
            if ((x1 * x1 + x2 * x2 )< 1 ) {
                break;
            }
        }

        let corrector1 = double ? 0.65 : 1
        let c = double ? corrector1/2 : 0

        let x=2*x1 * Math.sqrt(1-x1*x1-x2*x2) * corrector1
        let y=2*x2 * Math.sqrt(1-x1*x1-x2*x2) * corrector1
        let z=1-2*(x1*x1+x2*x2) * corrector1
		points1.push([
            0, 0, 0-c,
            x, y, z-c
        ])
	}


    return BABYLON.CreateGreasedLine("line1", { points: points1 },  { width: 0.05, color: pilliSecondColor, useColors: true })

}

function newSegment(double){
    let shape = BABYLON.MeshBuilder.CreateGeodesic("g", {m: 1, n: 0});
    shape.scaling = new BABYLON.Vector3(0.65, 0.65, 0.65)



	let lines = makeFluff(double, 2)




	if(double){

		lines2 = makeFluff(double, 2)
		lines.position.x -= 1

        second = newSegment(false)
        second.position.x = -1;
        shape = BABYLON.Mesh.MergeMeshes([shape, second]);

		lines2.parent = shape

    }

    lines.parent = shape
    shadowGenerator.getShadowMap().renderList.push(shape);

    return shape
}

function hinge(scene, innerSegments) {
    let catStart = newSegment(true) //BABYLON.MeshBuilder.CreateBox("catStart", {size: 1}, scene);
    catStart.position.x = curX;
    const col = addMat(catStart, scene);




    let catEnd = newSegment(true)
    catEnd.position.x = curX+innerSegments+0.8;
    addMat(catEnd, col, scene);

    //var pointerDragBehaviorEnd = new BABYLON.PointerDragBehavior({dragAxis: new BABYLON.Vector3(1,0,0)});
    //pointerDragBehaviorEnd.useObjectOrientationForDragging = false;
    //catEnd.addBehavior(pointerDragBehaviorEnd);

    //var pointerDragBehaviorStart = new BABYLON.PointerDragBehavior({dragAxis: new BABYLON.Vector3(1,0,0)});
    //pointerDragBehaviorStart.useObjectOrientationForDragging = false;
    //catStart.addBehavior(pointerDragBehaviorStart);

    let aggStart = new BABYLON.PhysicsAggregate(
        catStart,
        BABYLON.PhysicsShapeType.BOX,
        { mass: 0, restitution: resti, friction: fric },
        scene
    );
    aggStart.body.disablePreStep = false;


    let aggEnd = new BABYLON.PhysicsAggregate(
        catEnd,
        BABYLON.PhysicsShapeType.BOX,
        { mass: 0, restitution: resti, friction: fric },
        scene
    );
    aggEnd.body.disablePreStep = false;

    let joint = new BABYLON.HingeConstraint(
        new BABYLON.Vector3(0.5, 0, 0),
        new BABYLON.Vector3(-0.5, 0, 0),
        new BABYLON.Vector3(0, 0, 1),
        new BABYLON.Vector3(0, 0, 1),
        scene
    );

    let jointEnd = new BABYLON.HingeConstraint(
        new BABYLON.Vector3(0.5, 0, 0),
        new BABYLON.Vector3(-1.5, 0, 0),
        new BABYLON.Vector3(0, 0, 1),
        new BABYLON.Vector3(0, 0, 1),
        scene
    );

    let limAngle = new BABYLON.Physics6DoFConstraint({
        pivotA: new BABYLON.Vector3(0.5, 0, 0),
        pivotB: new BABYLON.Vector3(-0.5, 0, 0),

    }, [
        {axis: BABYLON.PhysicsConstraintAxis.ANGULAR_Z, maxLimit: 0.2}
    ], scene);

    let lastSegment = aggStart
    let middle
    let pilli = new BABYLON.TransformNode()
    catStart.parent = pilli
    catEnd.parent = pilli


    for(let i = 0; i<innerSegments; i++){
        let innerBox = newSegment()
        if(i == Math.floor(innerSegments/2)){
            middle = innerBox
        }
        addMat(innerBox, scene);

        let innerAgg = new BABYLON.PhysicsAggregate(
            innerBox,
            BABYLON.PhysicsShapeType.BOX,
            { mass: movingMass, restitution: resti, friction: fric },
            scene
        );

        lastSegment.body.addConstraint(innerAgg.body, joint);
        lastSegment.body.addConstraint(innerAgg.body, limAngle);

        lastSegment.body.setLinearDamping(20)

        lastSegment = innerAgg
        innerBox.parent = pilli


    }

    lastSegment.body.addConstraint(aggEnd.body, jointEnd);

    return [catStart, catEnd, middle, pilli]

};










function createTwig(scene){
		//Shape profile in XY plane
	const points = []
	const colors = []
	const widths = []
	for(let l = 0; l<40; l++){

		let line = []
		let wid = []
		let col = BABYLON.Color3.FromHexString("#4d401e")
        col.r -= BABYLON.Scalar.RandomRange(0,0.15)

		let maxA = Math.PI/20
		let lastA = Math.random() * Math.PI*2
		let radius = 3
		let w = Math.random()*4
		for(let i = 0; i<202; i++){
			var a = lastA + (Math.random() * maxA*2) - maxA

			line.push(i, Math.sin(a)*radius, Math.cos(a)*radius)
			lastA = a
			colors.push(col)
			widths.push(w)
			w += Math.random() -0.5
		}
		points.push(line)
		//widths.push(wid)
	}


    let twig = BABYLON.CreateGreasedLine("twig",
            { points: points, widths: widths, updatable: true },
            {
                width: 0.2,
                colors: colors,
                useColors: true,
                materialType: BABYLON.GreasedLineMeshMaterialType.MATERIAL_TYPE_PBR,
                colorMode: BABYLON.GreasedLineMeshColorMode.COLOR_MODE_MULTIPLY,
            })

    const pbr = twig.material
    pbr.metallic = 0.0;
    pbr.roughness = 1;

    pbr.subSurface.isRefractionEnabled = true;
    pbr.subSurface.indexOfRefraction = 1.8;



	const myPath = [
		 	new BABYLON.Vector3(0, 0, 0.0),
			new BABYLON.Vector3(200, 0, 0),
	];

	const tube = BABYLON.MeshBuilder.CreateTube("tube", {path: myPath, radius: 2.9, sideOrientation: BABYLON.Mesh.DOUBLESIDE}, scene);
	tube.parent = twig

	addWoodMaterial(tube)

    for(let x = 0; x<BABYLON.Scalar.RandomRange(10,40); x++){
        let miniTwig = createMiniTwig()
        miniTwig.position.x += BABYLON.Scalar.RandomRange(0, 200)
        miniTwig.parent = twig
    }


	twig.position.y -= 3.2
	//twig.position.x -= 100

	twigparts.push(twig)
	return twig
}

function createMiniTwig(){
    //Array of paths to construct tube
	const myPath = [
		 	new BABYLON.Vector3(0, 0, 0),
	];

    let nr = BABYLON.Scalar.RandomRange(3,6)
    for(let i = 0; i<nr; i++){
        myPath.push(new BABYLON.Vector3(0, i*3, BABYLON.Scalar.RandomRange(0,3)))
    }

    let thick = BABYLON.Scalar.RandomRange(0.05,0.2)
    const radiusChange = (index, distance) => {
        const radius =  (nr-index+1)*thick
        return radius;
    };

    //Create ribbon with updatable parameter set to true for later changes
	let tube = BABYLON.MeshBuilder.CreateTube("tube", {path: myPath, radiusFunction: radiusChange, sideOrientation: BABYLON.Mesh.DOUBLESIDE});
    addWoodMaterial(tube)
    tube.rotation.x = Math.PI/4
    tube.rotation.x += BABYLON.Scalar.RandomRange(0,Math.PI*1.5)
    //tube.rotate(new BABYLON.Vector3(0, 1, 0), Math.PI/4, BABYLON.Space.WORLD);

    return tube
}


function growTwig(twig){
	let twig2 = createTwig();

	const myPath = [
		 	new BABYLON.Vector3(0, 0, 0.0),
			new BABYLON.Vector3(200, 0, 0),
	];
	const tube = BABYLON.MeshBuilder.CreateTube("tube", {path: myPath, radius: 2.9, sideOrientation: BABYLON.Mesh.DOUBLESIDE});
	tube.parent = twig2
	addWoodMaterial(tube)


	twig2.position = twig.position.clone()
	twig2.position.x += 200
	//twig2.position.y -= 3.2
	//twigparts.push(twig2)
}



function upHappiness(){
     Tone.Transport.bpm.value = 120;
     curve.globalSaturation += 2;
     // pipeline.imageProcessing.contrast += 0.01;
     wiggleAnim.weight += 0.02
     bodycamAnim.weight += 0.01
     bodyCamRotationSpeed += 0.01
     if(wiggleAnim.weight > 0.7){
         if(part2 && part2.mute){
            part2.mute = false
            makeShield("just a", "stupid walk")
            makeShield2("for stupid", "mental health")


         }

     }


}

function downHappiness(){
    console.log("down")
     curve.globalSaturation -= 5;
     wiggleAnim.weight -= 0.02
     bodycamAnim.weight -= 0.02
     bodyCamRotationSpeed -= 0.02

     curve.globalSaturation = Math.max(curve.globalSaturation, 0);
     wiggleAnim.weight = Math.max(wiggleAnim.weight, 0);
     bodycamAnim.weight = Math.max(bodycamAnim.weight, 0);
     bodyCamRotationSpeed = Math.max(bodyCamRotationSpeed, 0.1);

     if(wiggleAnim.weight < 0.7){
         if(part2){part2.mute = true}
         makeShield("press key", "to pillar")
         //if(part2){part2.stop()}
     }


}
//
const createScene = async function () {

	var scene = new BABYLON.Scene(engine);
    //scene.createDefaultEnvironment();

    var helper = scene.createDefaultEnvironment({
            groundShadowLevel: 2,
            skyboxSize: 200,
            enableGroundShadow: false,
            groundOpacity: 0,
            //cameraContrast: 1.6,
            //cameraExposure: 0.5
        });

    helper.setMainColor(BABYLON.Color3.FromHexString("#556B2F"));



	// initialize plugin
	const havokInstance = await HavokPhysics();
	// pass the engine to the plugin
	const hk = new BABYLON.HavokPlugin(true, havokInstance);
	// enable physics in the scene with a gravity
	scene.enablePhysics(new BABYLON.Vector3(0, 50, 0), hk);





    let useViewer = true;

    // Physics engine
    var physicsViewer;
    if (useViewer) {
        physicsViewer = new BABYLON.PhysicsViewer();
    }
    // Camera
    //var camera = new BABYLON.FreeCamera(
    //    "camera1",
    //    new BABYLON.Vector3(0, 4, -24),
    //    scene
    //);
    //camera.setTarget(BABYLON.Vector3.Zero());


    bodycam = new BABYLON.FollowCamera("FollowCam", new BABYLON.Vector3(0, 1, -40), scene);
    bodycam.radius = 20;
	bodycam.heightOffset = 8;
	bodycam.rotationOffset = -20;
	bodycam.cameraAcceleration = 0.1
	bodycam.maxCameraSpeed = 10





    // Lightning

    var light = new BABYLON.HemisphericLight(
        "light1",
        new BABYLON.Vector3(0, 1, 0),
        scene
    );
    light.intensity = 0.7;



    var light2 = new BABYLON.DirectionalLight(
        "light2",
        new BABYLON.Vector3(0, -1, 1),
        scene
    );
    light2.position = new BABYLON.Vector3(0, 10, -10);
    light2.intensity = 5;
    shadowGenerator = new BABYLON.ShadowGenerator(1024, light2);




    // joints



    let [start, end, middle, p] = hinge(scene, segments);
    pilli = p
	let twig = createTwig(scene)
    twig.position.x -= 100



    scene.activeCamera = bodycam


    bodycam.lockedTarget = end;
	bodycam.attachControl(canvas);



    const beatAnim = new BABYLON.Animation("xSlide", "rotation.x", 60, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
    const keyFrames = [];
    let animLength = 60

    keyFrames.push({
        frame: 0,
        value: -0.8,
    });

    keyFrames.push({
        frame: animLength/2,
        value: 0.8,
    });

    keyFrames.push({
        frame: animLength,
        value: -0.8,
    });

    beatAnim.setKeys(keyFrames);
    const easingFunction = new BABYLON.CircleEase(); //PowerEase(5)   //CircleEase();
    easingFunction.setEasingMode(BABYLON.EasingFunction.EASINGMODE_EASEINOUT);
    beatAnim.setEasingFunction(easingFunction);
    pilli.animations.push(beatAnim);



    const camAnim = new BABYLON.Animation("xSlide2", "radius", 60, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
    const keyFrames2 = [];

    keyFrames2.push({
        frame: 0,
        value: 20,
    });

    keyFrames2.push({
        frame: animLength/2,
        value: 40,
    });

    keyFrames2.push({
        frame: animLength,
        value: 20,
    });

    camAnim.setKeys(keyFrames2);
    camAnim.setEasingFunction(easingFunction);
    bodycam.animations.push(camAnim);


    //scene.beginAnimation(pilli, 0, animLength, true);
    wiggleAnim = scene.beginWeightedAnimation(pilli, 0, animLength, 0, true);
    bodycamAnim = scene.beginWeightedAnimation(bodycam, 0, animLength, 0, true);




/*
	var lensEffect = new BABYLON.LensRenderingPipeline('lens', {
		edge_blur: 0,
		chromatic_aberration: 0,
		distortion: 0,
		dof_focus_distance: 20,
		dof_aperture: 0.5,			// set this very high for tilt-shift effect
		grain_amount: 0,
		dof_pentagon: true,
		dof_gain: 0,
		dof_threshold: 0.5,
		dof_darken: 1
	}, scene, 1.0, bodycam);
*/


	// Create default pipeline and enable dof with Medium blur level

    pipeline = new BABYLON.DefaultRenderingPipeline("default", true, scene, [scene.activeCamera]);
    pipeline.imageProcessing.contrast = 1.8; // 1 by default
    pipeline.imageProcessing.exposure = 1;
    /*pipeline.depthOfFieldBlurLevel = BABYLON.DepthOfFieldEffectBlurLevel.Low;
    pipeline.depthOfFieldEnabled = true;
    pipeline.depthOfField.focalLength = 150;
    pipeline.depthOfField.fStop = 0.5;
    pipeline.depthOfField.focusDistance = 17000;
	pipeline.sharpenEnabled = true;
    pipeline.bloomEnabled = false;
    */

    /*
    var curve = new BABYLON.ColorCurves();
    curve.globalDensity = 0; // 0 by default
    curve.globalExposure = 0; // 0 by default
    curve.globalHue = 0; // 30 by default
    curve.globalSaturation = 2; // 0 by default
    curve.highlightsDensity = 0; // 0 by default
    curve.highlightsExposure = 0; // 0 by default
    curve.highlightsHue = 30; // 30 by default
    curve.highlightsSaturation = 0; // 0 by default
    curve.midtonesDensity = 0; // 0 by default
    curve.midtonesExposure = 0; // 0 by default
    curve.midtonesHue = 30; // 30 by default
    curve.midtonesSaturation = 0; // 0 by default
    curve.shadowsDensity = 0; // 0 by default
    curve.shadowsExposure = 0; // 0 by default
    curve.shadowsHue = 30; // 30 by default
    curve.shadowsDensity = 80;
    curve.shadowsSaturation = 0; // 0 by default;
    */


    curve = new BABYLON.ColorCurves();
    curve.globalSaturation = -5; // 0 by default
    pipeline.imageProcessing.colorCurvesEnabled = true;
    pipeline.imageProcessing.colorCurves = curve;


    var postProcess = new BABYLON.ImageProcessingPostProcess("processing", 1.0, scene.activeCamera);
    postProcess.vignetteWeight = 5;
    postProcess.vignetteStretch = 1;
    postProcess.vignetteColor = new BABYLON.Color3.Black();
    postProcess.vignetteEnabled = true;



    //bodycam.inputs.attached.mousewheel.detachControl();
    //bodycam.inputs.attached.pointers.detachControl();

    scene.registerBeforeRender(function () {




			bodycam.rotationOffset += bodyCamRotationSpeed;

            let move = false

            if(endToggle){
                if(BABYLON.Vector3.Distance(start.position, end.position) > minDist){
                    start.position.x += 0.1 //pillispeed * scene.deltaTime
                    lastwalk = 0
                }
            }else{
                if(BABYLON.Vector3.Distance(start.position, end.position) < maxDist){
                    end.position.x += 0.1 //pillispeed * scene.deltaTime
                    lastwalk = 0
                    pilli.position.x -= 0.1
                    for(let t of twigparts){
                        t.position.x -= 0.1
                    }
                    for(let t of deletetwig){
                        t.position.x -= 0.1
                    }


                    if(twigparts[0].position.x < -100){
						console.log("grow")
						let lasttwig = twigparts.shift()
						growTwig(lasttwig)
						deletetwig.push(lasttwig)
						if(deletetwig.length > 3){
							let d = deletetwig.shift()
							d.dispose()
						}

					}


                }
            }

            lastwalk += scene.deltaTime
            if(lastwalk > 500){
                downHappiness()
                lastwalk = 0
            }

    });



    scene.onKeyboardObservable.add((kbInfo) => {
		switch (kbInfo.type) {
			case BABYLON.KeyboardEventTypes.KEYDOWN:

				endToggle = !endToggle
                upHappiness()
                lastwalk = 0

			break;
		}


	});


	return scene;
};



createScene().then((scene) => {
	engine.runRenderLoop(function () {
		if (scene) {
			scene.render();
		}
	});
});

document.addEventListener('click', async () => {
	await Tone.start()
	console.log('audio is ready')

    music()
    //Tone.Transport.start()
})

// Resize
window.addEventListener("resize", function () {
	engine.resize();
});
