devNotes 10-14-2016 Particle Spawner RT adjustment

fasdfdsfd2

CurFUTBW8AA8OAv


using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine.UI;


public class Argos_Particle_Spawner : MonoBehaviour
{
    struct Particle
    {
        public Vector3 position;
        public Vector3 velocity;
    }

    public bool bCompute_Running = false;

    public Transform Source_Transform;
    public UI_Ladder ui_Ladder;

    public int Attractor_Mode; //0 - Pendulum : 1 - Frisbee

    private int attractor_Count;

    private GameObject[] go_Atts = new GameObject[20];
    private float[] att_0 = new float[3];
    private float[] att_1 = new float[3];
    private float[] att_2 = new float[3];
    private float[] att_3 = new float[3];

    private float[] att_4 = new float[3];
    private float[] att_5 = new float[3];
    private float[] att_6 = new float[3];
    private float[] att_7 = new float[3];

    private float[] att_8 = new float[3];
    private float[] att_9 = new float[3];
    private float[] att_10 = new float[3];
    private float[] att_11 = new float[3];

    private float[] att_12 = new float[3];
    private float[] att_13 = new float[3];
    private float[] att_14 = new float[3];
    private float[] att_15 = new float[3];

    private float[] att_16 = new float[3];
    private float[] att_17 = new float[3];
    private float[] att_18 = new float[3];
    private float[] att_19 = new float[3];

    public Double_Slider color_double_slider;
    public Velocity_Color_Slider velocity_color_slider;

    public bool bPrimary;
    public UI_Control ui_control;
    public ShowHide_UI showHide_UI;
    public HMD_Ctrl_Tracking hmd_Ctrl_Tracking;
    public Text BlendMode_Txt;

    public Slider speedSwitch_Slider;
    float speedSwitch_Value;
    public Text speedSwitch_Text;

    public Slider constVel_Slider;
    float constVel_Value;
    public Text constVel_Text;

    public Slider geomScale_Slider;
    float geomScale_Value;
    public Text geomScale_Text;

    public ComputeShader computeShader;
    public Material material;
    public int maxParticles = 32;

    public GameObject pendulum_Handle; //Handle
    public GameObject orbitingSphere;

    public GameObject Frisbee;
    public GameObject Frisbee_Attractor_Right;
    public GameObject Frisbee_Attractor_Left;

    public Color_Swatches color_Swatches;

    public float targetStrength = 1000;//POWER MAG
    public float particle_size = 1f;
    public float timeMod = 1f;
    public float damping = 0f;
    public float orbit_weighting = 0.5f;

    public float radius_of_action = 1.0f;
    public float roa_amplitude = 0;
    public float roa_frequency = 0;
    public float constVel = 0;

    public float cubeSize = 100;

    public float maxAge = 3.0f;
    public float particleSize = 0.5f;

    private ComputeBuffer particles;
    private int particleSizeOf;
    private ComputeBuffer writeFromCompute;
    private int writeSizeOf;

    int kernel;

    public static List<Argos_Particle_Spawner> aps_list;// Static list, just to call Render() from the camera.

    void Start()
    {
        if (aps_list == null)
            aps_list = new List<Argos_Particle_Spawner>();
        aps_list.Add(this);

        StartCoroutine(Defer_LoadAttractors());
        attractor_Count = 0;
    }

    IEnumerator Defer_LoadAttractors()
    {
        yield return new WaitForSeconds(0.01f);
        hmd_Ctrl_Tracking.setAttractors(ref go_Atts, ref attractor_Count);
        bCompute_Running = true;
    }

    public void Set_Attractor_Mode(int mode)
    {
        Attractor_Mode = mode;
    }

    public void initParicleBuffer_Parbolic()
    {
        kernel = computeShader.FindKernel("CSMain");

        if (particles != null)
            particles.Dispose();
        particles = null;

        Particle p = new Particle();
        particleSizeOf = Marshal.SizeOf(p);
        Particle[] pInitBuffer = new Particle[maxParticles];

        int num = maxParticles;
        float fSeam = 0.5f;
        float offset = 1.0f / num;
        float increment = Mathf.PI * (3 - Mathf.Sqrt(5.0f));

        int idx = 0;
        Vector3 v;

        Vector3 pAdj;

        for (int i = 0; i < num; i++)
        {
            float y = (i * offset);
            float r = Mathf.Sqrt(y);
            float phi = ((i + fSeam) % num) * increment;
            float x = Mathf.Cos(phi) * r;
            float z = Mathf.Sin(phi) * r;

            v = new Vector3(x, y-0.5f, z);
            v *= geomScale_Value / 3f;

            //ADD ADJUSTMENT TRANSFORM;
            pAdj = v.x * Source_Transform.right + v.y * Source_Transform.up + v.z * Source_Transform.forward + Source_Transform.position;
            p.position = pAdj;
            p.velocity = Vector3.zero;

            pInitBuffer[idx] = p;
            idx++;
        }

        particles = new ComputeBuffer(maxParticles, particleSizeOf, ComputeBufferType.Default);
        particles.SetData(pInitBuffer);

        computeShader.SetBuffer(kernel, "particles", particles);
    }

    public void initParicleBuffer_Fibonacci()
    {
        kernel = computeShader.FindKernel("CSMain");

        if (particles != null)
            particles.Dispose();
        particles = null;

        Particle p = new Particle();
        particleSizeOf = Marshal.SizeOf(p);
        Particle[] pInitBuffer = new Particle[maxParticles];

        int num = maxParticles;
        float fSeam = 0.5f;
        float offset = 2.0f / num;
        float increment = Mathf.PI * (3 - Mathf.Sqrt(5.0f));

        int idx = 0;
        Vector3 v;

        Vector3 pAdj;

        for (int i = 0; i < num; i++)
        {
            float y = (i * offset) - 1 + (offset / 2.0f);
            float r = Mathf.Sqrt(1 - Mathf.Pow(y, 2));
            float phi = ((i + fSeam) % num) * increment;
            float x = Mathf.Cos(phi) * r;
            float z = Mathf.Sin(phi) * r;

            v = new Vector3(x, y, z);
            v *= geomScale_Value/3f;

            //ADD ADJUSTMENT TRANSFORM;
            pAdj = v.x * Source_Transform.right + v.y * Source_Transform.up + v.z * Source_Transform.forward + Source_Transform.position;
            p.position = pAdj;
            p.velocity = Vector3.zero;

            pInitBuffer[idx] = p;
            idx++;
        }

        particles = new ComputeBuffer(maxParticles, particleSizeOf, ComputeBufferType.Default);
        particles.SetData(pInitBuffer);

        computeShader.SetBuffer(kernel, "particles", particles);
    }

    void initParicleBuffer_Laminar()
    {
        kernel = computeShader.FindKernel("CSMain");

        if (particles != null)
            particles.Dispose();
        particles = null;

        Particle p = new Particle();
        particleSizeOf = Marshal.SizeOf(p);
        Particle[] pInitBuffer = new Particle[maxParticles];

        float sideCount = Mathf.Floor(Mathf.Sqrt(((float)maxParticles)/4f));

        float edgeDist = 1f / sideCount;

        float startX, startY, startZ;
        float rideX, rideY, rideZ;
        startX = startZ = rideX = rideZ = (int)((-sideCount / 2.0f) * edgeDist);
        startY = rideY = -2* edgeDist;

        int nSideCount = (int)sideCount;

        int idx = 0;

        Vector3 v;
        Vector3 pAdj;

        for (int i = 0; i < nSideCount; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                for (int k = 0; k < nSideCount; k++)
                {
                    p = new Particle();
                    v.x = rideX;
                    v.y = rideY;
                    v.z = rideZ;

                    v *= geomScale_Value;

                    pAdj = v.x * Source_Transform.right + v.y * Source_Transform.up + v.z * Source_Transform.forward + Source_Transform.position;

                    p.position = pAdj;
                    p.velocity = Vector3.zero;



                    pInitBuffer[idx] = p;

                    rideX += edgeDist;
                    idx++;
                }
                rideX = startX;
                rideY += edgeDist;
            }
            rideX = startX;
            rideY = startY;
            rideZ += edgeDist;
        }
        particles = new ComputeBuffer(maxParticles, particleSizeOf, ComputeBufferType.Default);
        particles.SetData(pInitBuffer);

        computeShader.SetBuffer(kernel, "particles", particles);
    }

    void initParicleBuffer_Cube()
    {
        kernel = computeShader.FindKernel("CSMain");

        if (particles != null)
            particles.Dispose();
        particles = null;

        Particle p = new Particle();
        particleSizeOf = Marshal.SizeOf(p);
        Particle[] pInitBuffer = new Particle[maxParticles];

        float sideCount = Mathf.Floor(Mathf.Pow((float)maxParticles, 1.0f / 3.0f));

        float edgeDist = 1f / sideCount;

        float startX, startY, startZ;
        float rideX, rideY, rideZ;
        startX = startZ = rideX = rideZ = (int)((-sideCount / 2.0f) * edgeDist);
        startY = rideY = (int)((-sideCount / 2.0f) * edgeDist);

        int nSideCount = (int)sideCount;

        int idx = 0;

        Vector3 v;
        Vector3 pAdj;

        for (int i = 0; i < nSideCount; i++)
        {
            for (int j = 0; j < nSideCount; j++)
            {
                for (int k = 0; k < nSideCount; k++)
                {
                    p = new Particle();
                    //p.index = i;
                    //p.type = 0;
                    //p.age = 0;
                    //p.normAge = 0.1f;
                    //p.size = particleSize * 0.5f + particleSize;
                    //if (bPrimary)//Hack
                    //{
                    v.x = rideX;
                    v.y = rideY;
                    v.z = rideZ;

                    v *= geomScale_Value;

                    //v += vert_Offset;
                    pAdj = v.x * Source_Transform.right + v.y * Source_Transform.up + v.z * Source_Transform.forward + Source_Transform.position;
                    p.position = pAdj;
                    p.velocity = Vector3.zero;

                    pInitBuffer[idx] = p;

                    rideX += edgeDist;
                    idx++;
                }
                rideX = startX;
                rideY += edgeDist;
            }
            rideX = startX;
            rideY = startY;
            rideZ += edgeDist;
        }
        particles = new ComputeBuffer(maxParticles, particleSizeOf, ComputeBufferType.Default);
        particles.SetData(pInitBuffer);

        computeShader.SetBuffer(kernel, "particles", particles);
    }

    public void ResetCube()
    {
        initParicleBuffer_Cube();
    }

    public void ResetFibonacci()
    {
        initParicleBuffer_Fibonacci();
    }

    public void ResetLaminarFlow()
    {
        initParicleBuffer_Laminar();
    }

    public void ResetParabolic()
    {
        initParicleBuffer_Parbolic();
    }

    public void onZeroVelocity()
    {
        constVel_Slider.value = 0; 
    }

    public void onSpeedSwitchSlider()
    {
        if (bPrimary)
        {
            speedSwitch_Value = speedSwitch_Slider.value*2000f;
            speedSwitch_Text.text = speedSwitch_Value.ToString("F2");
            UI_Ladder.Instance.fine_Tuner.Active_FTS(speedSwitch_Slider);
        }
     }

    public void onConstVelSlider()
    {
        if (bPrimary)
        {
            constVel_Value = constVel_Slider.value;
            constVel_Text.text = constVel_Slider.value.ToString("F2");
            UI_Ladder.Instance.fine_Tuner.Active_FTS(constVel_Slider);
        }
    }

    public void onGeomScaleSlider()
    {
        if (bPrimary)
        {
            geomScale_Value = geomScale_Slider.value;
            geomScale_Text.text = geomScale_Value.ToString("F2");
            UI_Ladder.Instance.fine_Tuner.Active_FTS(geomScale_Slider);
        }
    }

    public void returnMasses_ToSpawn()
    {
        pendulum_Handle.GetComponent<Return_to_Spawn>().ResetToSpawn();
        orbitingSphere.GetComponent<Return_to_Spawn>().ResetToSpawn();
        Frisbee.GetComponent<Return_to_Spawn>().ResetToSpawn();
    }


    public void SetAttractorCount(int cnt)
    {
        attractor_Count = cnt;
    }

    private void attractor_Frame_Gather()
    {
        att_0[0] = go_Atts[0].transform.position.x;
        att_0[1] = go_Atts[0].transform.position.y;
        att_0[2] = go_Atts[0].transform.position.z;

        att_1[0] = go_Atts[1].transform.position.x;
        att_1[1] = go_Atts[1].transform.position.y;
        att_1[2] = go_Atts[1].transform.position.z;

        att_2[0] = go_Atts[2].transform.position.x;
        att_2[1] = go_Atts[2].transform.position.y;
        att_2[2] = go_Atts[2].transform.position.z;

        att_3[0] = go_Atts[3].transform.position.x;
        att_3[1] = go_Atts[3].transform.position.y;
        att_3[2] = go_Atts[3].transform.position.z;

        att_4[0] = go_Atts[4].transform.position.x;
        att_4[1] = go_Atts[4].transform.position.y;
        att_4[2] = go_Atts[4].transform.position.z;

        att_5[0] = go_Atts[5].transform.position.x;
        att_5[1] = go_Atts[5].transform.position.y;
        att_5[2] = go_Atts[5].transform.position.z;

        att_6[0] = go_Atts[6].transform.position.x;
        att_6[1] = go_Atts[6].transform.position.y;
        att_6[2] = go_Atts[6].transform.position.z;

        att_7[0] = go_Atts[7].transform.position.x;
        att_7[1] = go_Atts[7].transform.position.y;
        att_7[2] = go_Atts[7].transform.position.z;


        att_8[0] = go_Atts[8].transform.position.x;
        att_8[1] = go_Atts[8].transform.position.y;
        att_8[2] = go_Atts[8].transform.position.z;

        att_9[0] = go_Atts[9].transform.position.x;
        att_9[1] = go_Atts[9].transform.position.y;
        att_9[2] = go_Atts[9].transform.position.z;

        att_10[0] = go_Atts[10].transform.position.x;
        att_10[1] = go_Atts[10].transform.position.y;
        att_10[2] = go_Atts[10].transform.position.z;

        att_11[0] = go_Atts[11].transform.position.x;
        att_11[1] = go_Atts[11].transform.position.y;
        att_11[2] = go_Atts[11].transform.position.z;


        att_12[0] = go_Atts[12].transform.position.x;
        att_12[1] = go_Atts[12].transform.position.y;
        att_12[2] = go_Atts[12].transform.position.z;

        att_13[0] = go_Atts[13].transform.position.x;
        att_13[1] = go_Atts[13].transform.position.y;
        att_13[2] = go_Atts[13].transform.position.z;

        att_14[0] = go_Atts[14].transform.position.x;
        att_14[1] = go_Atts[14].transform.position.y;
        att_14[2] = go_Atts[14].transform.position.z;

        att_15[0] = go_Atts[15].transform.position.x;
        att_15[1] = go_Atts[15].transform.position.y;
        att_15[2] = go_Atts[15].transform.position.z;


        att_16[0] = go_Atts[16].transform.position.x;
        att_16[1] = go_Atts[16].transform.position.y;
        att_16[2] = go_Atts[16].transform.position.z;

        att_17[0] = go_Atts[17].transform.position.x;
        att_17[1] = go_Atts[17].transform.position.y;
        att_17[2] = go_Atts[17].transform.position.z;

        att_18[0] = go_Atts[18].transform.position.x;
        att_18[1] = go_Atts[18].transform.position.y;
        att_18[2] = go_Atts[18].transform.position.z;

        att_19[0] = go_Atts[19].transform.position.x;
        att_19[1] = go_Atts[19].transform.position.y;
        att_19[2] = go_Atts[19].transform.position.z;
    }

    void FixedUpdate()
    {
        if (bCompute_Running)
        {
            if (go_Atts[0] != null)
            {
                attractor_Frame_Gather();
            }
            computeShader.SetFloat("time", Time.time);

            float[] targ1 = { 0f, 0f, 0f };
            float[] targ2 = { 0f, 0f, 0f };

            Vector3 pos;
            if (Attractor_Mode == 0)
            {
                pos = pendulum_Handle.transform.position;
            }
            else
            {
                pos = Frisbee_Attractor_Left.transform.position;
            }
            targ1[0] = pos.x;
            targ1[1] = pos.y;
            targ1[2] = pos.z;

            if (Attractor_Mode == 0)
            {
                pos = orbitingSphere.transform.position;
            }
            else
            {
                pos = Frisbee_Attractor_Right.transform.position;
            }

            targ2[0] = pos.x;
            targ2[1] = pos.y;
            targ2[2] = pos.z;

            orbit_weighting = 0.5f;

            targetStrength = ui_Ladder.pParticlePower;
            orbit_weighting = ui_control.orbit_weighting;
            particleSize = ui_Ladder.particleSize;
            radius_of_action = ui_control.Radius_of_Action;
            roa_amplitude = ui_control.ROA_Amplitude;
            roa_frequency = ui_control.ROA_Frequency;

            modulate_ROA();

            if (ui_Ladder.bStop_Time_Tog_On)
            {
                timeMod = 0;
            }
            else
            {
                timeMod = ui_Ladder.timeMod_Val * 1f / 90f;
            }

            damping = 1 - 0.05f * ui_Ladder.damping_Val;

            // Initialise the compute shader variables.
            computeShader.SetFloat("targetStrengh", targetStrength);
            computeShader.SetFloat("deltaTime", timeMod);
            computeShader.SetFloat("damping", damping);
            computeShader.SetFloats("base", targ1);
            computeShader.SetFloats("orbit", targ2);
            computeShader.SetFloat("orbit_weighting", orbit_weighting);
            computeShader.SetFloat("radius_of_action", radius_of_action);
            computeShader.SetFloat("constVel", constVel_Value*3000f);

            computeShader.SetFloats("att_0", att_0);
            computeShader.SetFloats("att_1", att_1);
            computeShader.SetFloats("att_2", att_2);
            computeShader.SetFloats("att_3", att_3);

            computeShader.SetFloats("att_4", att_4);
            computeShader.SetFloats("att_5", att_5);
            computeShader.SetFloats("att_6", att_6);
            computeShader.SetFloats("att_7", att_7);

            computeShader.SetFloats("att_8", att_8);
            computeShader.SetFloats("att_9", att_9);
            computeShader.SetFloats("att_10", att_10);
            computeShader.SetFloats("att_11", att_11);

            computeShader.SetFloats("att_12", att_12);
            computeShader.SetFloats("att_13", att_13);
            computeShader.SetFloats("att_14", att_14);
            computeShader.SetFloats("att_15", att_15);

            computeShader.SetFloats("att_16", att_16);
            computeShader.SetFloats("att_17", att_17);
            computeShader.SetFloats("att_18", att_18);
            computeShader.SetFloats("att_19", att_19);

            computeShader.SetInt("attractor_Count", attractor_Count);

            uint x, y, z;
            computeShader.GetKernelThreadGroupSizes(kernel, out x, out y, out z);
            computeShader.Dispatch(kernel, maxParticles, 1, 1);
        }
    }

    void modulate_ROA()
    {
        float unit = radius_of_action;
        float amp = unit * roa_amplitude;
        radius_of_action = unit + amp * Mathf.Sin(roa_frequency * Time.time * 2 * Mathf.PI);
    }

    // Called by the PendulumRender in OnRender
    public void Render()
    {
        if (bPrimary)
        {
            material.SetPass(0);
            material.SetVector("_worldpos", transform.position);
            material.SetBuffer("particles", particles);
            material.SetFloat("_particleSize", particleSize);
            material.SetColor("_LowColor", color_Swatches.Low_Color);
            material.SetColor("_MidColor", color_Swatches.Mid_Color);
            material.SetColor("_HighColor", color_Swatches.High_Color);
            material.SetFloat("_colorSwitch", speedSwitch_Value);
            material.SetFloat("_LowMidThresh", velocity_color_slider.getLowMid_Threshold());
            material.SetFloat("_HighMidThresh", velocity_color_slider.getMidHigh_Threshold());
            material.SetFloat("_nPerc", ui_Ladder.pctBandColorLrp);

            int blendMode = ui_Ladder.getBlendMode();
            //BlendMode_Txt.text = blendMode.ToString();

            if (blendMode == 0)
            {
                material.SetInt("_ARG_SrcMode", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
                material.SetInt("_ARG_DstMode", (int)UnityEngine.Rendering.BlendMode.Zero);
            }
            else if (blendMode == 1)
            {
                material.SetInt("_ARG_SrcMode", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
                material.SetInt("_ARG_DstMode", (int)UnityEngine.Rendering.BlendMode.One);
            }
            else
            {
                material.SetInt("_ARG_SrcMode", (int)UnityEngine.Rendering.BlendMode.SrcColor);
                material.SetInt("_ARG_DstMode", (int)UnityEngine.Rendering.BlendMode.DstColor);
            }

            Graphics.DrawProcedural(MeshTopology.Points, maxParticles, 0);
        }
    }

    void OnDisable()
    {
        particles.Release();
    }
}