5/11/21

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Lissajous_3D : MonoBehaviour
{
    public float angle = 0.0f;

    public float scale = 1;
    public float timeScale = 1;
    public float xMult = 1;
    public float yMult = 1;
    public float zMult = 1;

    public float zPhase = 0;



    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        angle += timeScale*Time.deltaTime;

        transform.localPosition = scale * (new Vector3(Mathf.Cos(xMult * angle), Mathf.Sin(yMult * angle), Mathf.Cos(zMult * angle + zPhase*Mathf.PI/180)));
    }



}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


namespace BNG {


    public class ARGOS_Character_Movement : MonoBehaviour
    {
        public enum LOC_Mode
        {
            NORMAL,
            GRAB_SPACE,
        };

        public enum HAND
        {
            RIGHT,
            LEFT,
        };

        private Vector3 swimTran;

        //FLOATING ROTATIONS
        private float rightHand_Damped_Angle = 0f;
        private Vector3 rightHand_Damped_AXIS = Vector3.one;

        private float leftHand_Damped_Angle = 0f;
        private Vector3 leftHand_Damped_AXIS = Vector3.one;        
        //rotational Amp flow
        [Range(0f, 50f)]
        public float swimAmp_Rota;

        //Angs Accum
        private float[] qRotaAngs_RH = new float[20];
        private int qRH_RA_idx = 0;
        private float[] qRotaAngs_LH = new float[20];
        private int qLH_RA_idx = 0;


        [Range(0f, 500f)]
        public float angularFlow_LowBound = 0.5f;

        //LINEAR FLOW
        //Where to stop damped linear movement on Grab
        //linear Amp mod Flow
        [Range(0f, 500f)]
        public float swimAmplification;

        [Range(0f, 100f)]
        public float linearFlow_LowBound = 0.04f;

        //vTRANS ACCUM
        private Vector3[] vTrans = new Vector3[20];
        private int vTransIDX = 0;



        public LOC_Mode locomotionMODE = LOC_Mode.NORMAL;

        public Material LH_Material_GrabSpace;
        public Material RH_Material_GrabSpace;

        public Material LH_Material_NORMAL;
        public Material RH_Material_NORMAL;

        public SkinnedMeshRenderer skinnedMesh_LH;
        public SkinnedMeshRenderer skinnedMesh_RH;

        private Vector3 slerp_Ctrl_Pos_Right;
        private Quaternion slerp_Rotation_Right;

        private Vector3 slerp_Ctrl_Pos_Left;
        private Quaternion slerp_Rotation_Left;

        private Vector3 vCtrl1_Last_Pos;
        private Vector3 vCtrl2_Last_Pos;
        private Vector3 vCtrl1_Right;
        private Vector3 vCtrl1_Last_Right;
        private Vector3 vCtrl1_Up;
        private Vector3 vCtrl1_Last_Up;

        private Vector3 vCtrl2_Right;
        private Vector3 vCtrl2_Last_Right;
        private Vector3 vCtrl2_Up;
        private Vector3 vCtrl2_Last_Up;

        private Vector3 slerp_Ctrl_Pos_1;
        private Quaternion slerp_Rotation_1;

        private Vector3 slerp_Ctrl_Pos_2;
        private Quaternion slerp_Rotation_2;
        public float grab_Rotate_Damping = 1.61803f;

        public float JetForce = 10;
        public Transform rightController;
        public Transform leftController;

        Vector3 accumVector_LH;
        Vector3 accumVector_RH;

        public Transform head;

        int countDamp;
        public int dampFrameCount;
        private List<Vector3> moveStack_LH = new List<Vector3>();
        private List<Vector3> moveStack_RH = new List<Vector3>();

        [Header("Input")]
        [Tooltip("Set to false to skip Update")]
        public bool AllowInput = true;

        [Tooltip("Used to determine whether to turn left / right. This can be an X Axis on the thumbstick, for example. -1 to snap left, 1 to snap right.")]
        public List<InputAxis> inputAxis_LH = new List<InputAxis>() { InputAxis.LeftThumbStickAxis };
        public List<InputAxis> inputAxis_RH = new List<InputAxis>() { InputAxis.RightThumbStickAxis };

        [Tooltip("How fast to rotate the player if RotationType is set to 'Smooth'")]
        public float SmoothTurnSpeed = 40f;

        [Tooltip("Thumbstick X axis must be >= this amount to be considered an input event")]
        public float SmoothTurnMinInput = 0.1f;

        [Header("Keyboard Input")]
        /// <summary>
        /// Allow Q,E to rotate player
        /// </summary>
        [Tooltip("Allow Q,E to rotate player")]
        public bool AllowKeyboardInputs = true;

        Grabber leftGrabber = null;
        Grabber rightGrabber = null;
        bool ahandOccupied = false;

        void Start()
        {
            for (int i = 0; i < dampFrameCount; i++)
            {
                moveStack_LH.Add(new Vector3(0, 0, 0));
                moveStack_RH.Add(new Vector3(0, 0, 0));
            }

            // Assign left / right grabbers
            Grabber[] grabs = GameObject.FindGameObjectWithTag("Player").GetComponentsInChildren<Grabber>();
            foreach (var g in grabs)
            {
                if (g.HandSide == ControllerHand.Left)
                {
                    leftGrabber = g;
                }
                else if (g.HandSide == ControllerHand.Right)
                {
                    rightGrabber = g;
                }
            }
        }

        private void Assign_Grabbers()
        {
            Grabber[] grabs = GameObject.FindGameObjectWithTag("Player").GetComponentsInChildren<Grabber>();
            foreach (var g in grabs)
            {
                if (g.HandSide == ControllerHand.Left)
                {
                    leftGrabber = g;
                }
                else if (g.HandSide == ControllerHand.Right)
                {
                    rightGrabber = g;
                }
            }
        }


        void Update()
        {
            if (!AllowInput) {
                return;
            }

            if (!rightGrabber || !leftGrabber)
            {
                Assign_Grabbers();
                return; //skip the rest until we've got them
            }

            Swimming_In_The_VU();
            DoSmoothRotation();

            if (BNG.InputBridge.Instance.RightThumbstickDown)
            {
                if (locomotionMODE == LOC_Mode.NORMAL)
                {
                    locomotionMODE = LOC_Mode.GRAB_SPACE;
                    skinnedMesh_LH.material = LH_Material_GrabSpace;
                    skinnedMesh_RH.material = RH_Material_GrabSpace;
                }
                else
                {
                    locomotionMODE = LOC_Mode.NORMAL;
                    skinnedMesh_LH.material = LH_Material_NORMAL;
                    skinnedMesh_RH.material = RH_Material_NORMAL;
                }
            }
        }

        public void Swimming_In_The_VU()
        {
            Vector3 currSwimTran = Vector3.zero;
            float currSwimQ_Angle_RH = 0f;
            float currSwimQ_Angle_LH = 0f;

            // Holding Items

            bool rh_occupied = false;
            bool lh_occupied = false;
            if (rightGrabber.HoldingItem)
            {
                rh_occupied = true;
            }
            if (leftGrabber.HoldingItem)
            {
                lh_occupied = true;
            }
            if (rh_occupied || lh_occupied)
            {
                ahandOccupied = true;
            }
            Vector3 axis;
            float angle;

            float fRH_GRIP = BNG.InputBridge.Instance.RightGrip;
            float fLH_GRIP = BNG.InputBridge.Instance.LeftGrip;

            bool bRH_GRIP_PRESSED = fRH_GRIP > 0.0f;
            bool bLH_GRIP_PRESSED = fLH_GRIP > 0.0f;

            bool bAGripPressed = bRH_GRIP_PRESSED || bLH_GRIP_PRESSED;

            if (bRH_GRIP_PRESSED && !rh_occupied)
            {
                //print("Climb Frame Trigger & bClimb -  1");
                vCtrl1_Right = rightController.transform.right;
                Quaternion q = Quaternion.FromToRotation(vCtrl1_Right, vCtrl1_Last_Right);

                vCtrl1_Up = rightController.transform.up;
                Quaternion q2 = Quaternion.FromToRotation(vCtrl1_Up, vCtrl1_Last_Up);
                Quaternion q3 = q * q2;

                slerp_Ctrl_Pos_1 = Vector3.Slerp(slerp_Ctrl_Pos_1, rightController.transform.position, Time.deltaTime * grab_Rotate_Damping);

                slerp_Rotation_1 = Quaternion.Slerp(slerp_Rotation_1, q3, Time.deltaTime * grab_Rotate_Damping);

                slerp_Rotation_1.ToAngleAxis(out angle, out axis);

                transform.RotateAround(rightController.transform.position, axis, angle * 0.99f);

                Flow_Angular_Movement(angle, ref currSwimQ_Angle_RH, ref qRH_RA_idx, HAND.RIGHT);

                //if (angle < 0.5f)//No flowing rotation if below this value
                //{
                //    angle = 0;
                //}
                //currSwimQ_Angle_RH = angle;

                rightHand_Damped_AXIS = axis;

            }
            else if (bLH_GRIP_PRESSED && !lh_occupied)
            {
                //print("Climb Frame Trigger & bClimb -  2");
                vCtrl2_Right = leftController.transform.right;
                Quaternion q = Quaternion.FromToRotation(vCtrl2_Right, vCtrl2_Last_Right);

                vCtrl2_Up = leftController.transform.up;
                Quaternion q2 = Quaternion.FromToRotation(vCtrl2_Up, vCtrl2_Last_Up);
                Quaternion q3 = q * q2;
                slerp_Ctrl_Pos_2 = Vector3.Slerp(slerp_Ctrl_Pos_2, leftController.transform.position, Time.deltaTime * grab_Rotate_Damping);

                slerp_Rotation_2 = Quaternion.Slerp(slerp_Rotation_2, q3, Time.deltaTime * grab_Rotate_Damping);

                slerp_Rotation_2.ToAngleAxis(out angle, out axis);

                transform.RotateAround(leftController.transform.position, axis, angle * 0.99f);

                Flow_Angular_Movement(angle, ref currSwimQ_Angle_LH, ref qLH_RA_idx, HAND.LEFT);

                //if (angle < 0.5f)//No flowing rotation if below this value
                //{
                //    angle = 0;
                //}
                //currSwimQ_Angle_LH = angle;

                leftHand_Damped_AXIS = axis;

            }

            float c = 1;
            //if (current_USER_LOCATION == USER_LOCATION.IN_THE_VU)
            //{
            //    c = curr_Flight_Tran;
            //}

            //Linear Movement
            if (bRH_GRIP_PRESSED && !rh_occupied)
            {
                //print("Climb Frame GRIP & bClimb -  1");
                Vector3 vDelt = rightController.transform.position -vCtrl1_Last_Pos;
                Vector3 vTran = c * vDelt; //argos_Teleport.transform.InverseTransformDirection(c * vDelt);
                transform.position -= vTran;

                Flow_Linear_Movement(vTran, ref currSwimTran);
                //currSwimTran -= vTran;
                //VU_UI.transform.position -= vTran;
            }
            else if (bLH_GRIP_PRESSED && !lh_occupied)
            {
                //print("Climb Frame GRIP & bClimb -  2");
                Vector3 vDelt = leftController.transform.position - vCtrl2_Last_Pos;
                Vector3 vTran = c * vDelt; //argos_Teleport.transform.InverseTransformDirection(c *vDelt);
                transform.position -= vTran;

                Flow_Linear_Movement(vTran, ref currSwimTran);
                //currSwimTran -= vTran;
            }

            //Clear State
            if (!bAGripPressed)
            {
                if (true)
                {
                    //slerp_Ctrl_Pos_1 = ctrl1.transform.position;
                    //slerp_Rotation_1 = Quaternion.identity;

                    vCtrl1_Right = rightController.transform.right;
                    Quaternion q = Quaternion.FromToRotation(vCtrl1_Right, vCtrl1_Right);

                    vCtrl1_Up = rightController.transform.up;
                    Quaternion q2 = Quaternion.FromToRotation(vCtrl1_Up, vCtrl1_Up);
                    Quaternion q3 = q * q2;

                    slerp_Ctrl_Pos_1 = rightController.transform.position;

                    slerp_Rotation_1 = q3;
                }
                if (true)
                {
                    //slerp_Ctrl_Pos_2 = ctrl2.transform.position;
                    //slerp_Rotation_2 = Quaternion.identity;

                    vCtrl2_Right = leftController.transform.right;
                    Quaternion q = Quaternion.FromToRotation(vCtrl2_Right, vCtrl2_Right);

                    vCtrl2_Up = leftController.transform.up;
                    Quaternion q2 = Quaternion.FromToRotation(vCtrl2_Up, vCtrl2_Up);
                    Quaternion q3 = q * q2;
                    slerp_Ctrl_Pos_2 = leftController.transform.position;

                    slerp_Rotation_2 = q3;
                }

                if (true /*active_Ctrl_States.bCtrl_1_On*/)
                {
                    //slerp_Ctrl_Pos_1 = ctrl1.transform.position;
                    //slerp_Rotation_1 = Quaternion.identity;

                    vCtrl1_Right = rightController.transform.right;
                    Quaternion q = Quaternion.FromToRotation(vCtrl1_Right, vCtrl1_Right);

                    vCtrl1_Up = rightController.transform.up;
                    Quaternion q2 = Quaternion.FromToRotation(vCtrl1_Up, vCtrl1_Up);
                    Quaternion q3 = q * q2;

                    slerp_Ctrl_Pos_1 = rightController.transform.position;

                    slerp_Rotation_1 = q3;
                }
                if (true/*active_Ctrl_States.bCtrl_2_On*/)
                {
                    //slerp_Ctrl_Pos_2 = ctrl2.transform.position;
                    //slerp_Rotation_2 = Quaternion.identity;

                    vCtrl2_Right = leftController.transform.right;
                    Quaternion q = Quaternion.FromToRotation(vCtrl2_Right, vCtrl2_Right);

                    vCtrl2_Up = leftController.transform.up;
                    Quaternion q2 = Quaternion.FromToRotation(vCtrl2_Up, vCtrl2_Up);
                    Quaternion q3 = q * q2;
                    slerp_Ctrl_Pos_2 = leftController.transform.position;

                    slerp_Rotation_2 = q3;
                }
            }
            vCtrl1_Last_Right = rightController.transform.right;
            vCtrl2_Last_Right = leftController.transform.right;
            vCtrl1_Last_Up = rightController.transform.up;
            vCtrl2_Last_Up = leftController.transform.up;

            vCtrl1_Last_Pos = rightController.transform.position;
            vCtrl2_Last_Pos = leftController.transform.position;

            //SWIM Tran
            swimTran = Vector3.Lerp(swimTran, currSwimTran, 0.1f*Time.deltaTime );
            transform.position += swimAmplification*swimTran;

            if (bRH_GRIP_PRESSED)
            {
                rightHand_Damped_Angle = currSwimQ_Angle_RH;
                //    rightHand_Damped_Angle = Mathf.Lerp(rightHand_Damped_Angle, 0, Time.deltaTime);
                //    transform.RotateAround(rightController.transform.position, rightHand_Damped_AXIS, rightHand_Damped_Angle * swimAmp_Rota);
            }
            else
            {
                rightHand_Damped_Angle = Mathf.Lerp(rightHand_Damped_Angle, currSwimQ_Angle_RH, 0.1f*Time.deltaTime);
                transform.RotateAround(rightController.transform.position, rightHand_Damped_AXIS, rightHand_Damped_Angle * swimAmp_Rota);
            }
            if (bLH_GRIP_PRESSED)
            {
                leftHand_Damped_Angle = currSwimQ_Angle_LH;
                //    rightHand_Damped_Angle = Mathf.Lerp(rightHand_Damped_Angle, 0, Time.deltaTime);
                //    transform.RotateAround(rightController.transform.position, rightHand_Damped_AXIS, rightHand_Damped_Angle * swimAmp_Rota);
            }
            else
            {
                leftHand_Damped_Angle = Mathf.Lerp(leftHand_Damped_Angle, currSwimQ_Angle_LH, 0.1f * Time.deltaTime);
                transform.RotateAround(leftController.transform.position, leftHand_Damped_AXIS, leftHand_Damped_Angle * swimAmp_Rota);
            }
        }

        public void Flow_Angular_Movement(float qAngle, ref float currSwimQ_Angle, ref int idx, HAND hand)
        {
            float[] accum = null;

            if(hand == HAND.RIGHT)
            {
                accum = qRotaAngs_RH;
            }
            else
            {
                accum = qRotaAngs_LH;
            }
            if (++idx >= accum.Length) idx = 0;

            accum[idx] = qAngle;

            float qaAVE = 0;
            for(int i = 0; i < accum.Length;i++)
            {
                qaAVE += qAngle;
            }
            qaAVE /= accum.Length;

            if(qaAVE < (angularFlow_LowBound/10)*Time.deltaTime)
            {
                currSwimQ_Angle = 0;
                if (hand == HAND.RIGHT) rightHand_Damped_Angle = 0;
                else
                if (hand == HAND.LEFT) leftHand_Damped_Angle = 0;

                for (int i = 0; i < accum.Length; i++)
                {
                    accum[i] = 0f;
                }
            }
            else
            {
                currSwimQ_Angle = qaAVE;
            }
        }


        public void Flow_Linear_Movement(Vector3 vTran, ref Vector3 currSwimTran)
        {
            if (++vTransIDX >= vTrans.Length) vTransIDX = 0;

            vTrans[vTransIDX] = vTran;
            Vector3 vAVE = Vector3.zero;
            for(int i = 0; i < vTrans.Length; i++)
            {
                vAVE += vTrans[i];
            }
            vAVE /= vTrans.Length;

            if (vAVE.magnitude < (linearFlow_LowBound / 1000f) * Time.deltaTime)
            {
                currSwimTran = Vector3.zero;
                swimTran = Vector3.zero;

                for (int i = 0; i < vTrans.Length; i++)
                {
                    vTrans[i] = Vector3.zero;
                }
            }
            else
            {
                currSwimTran = -vAVE;
            }
        }

        public virtual void DoSmoothRotation()
        {

            Vector2 axisVal_LH = BNG.InputBridge.Instance.GetInputAxisValue(inputAxis_LH[0]);
            Vector2 axisVal_RH = BNG.InputBridge.Instance.GetInputAxisValue(inputAxis_RH[0]);

            // Reset rotation amount before retrieving inputs
            float rotationAmount = 0;
            float xInput = axisVal_LH.x;

            // Smooth Rotate Right
            if (xInput >= SmoothTurnMinInput) {
                rotationAmount += xInput * xInput * xInput * SmoothTurnSpeed * Time.deltaTime;
            }
            // Smooth Rotate Left
            else if (xInput <= -SmoothTurnMinInput) {
                rotationAmount += xInput * xInput * xInput * SmoothTurnSpeed * Time.deltaTime;
            }

            // Apply rotation
            transform.rotation = Quaternion.Euler(new Vector3(transform.eulerAngles.x, transform.eulerAngles.y + rotationAmount, transform.eulerAngles.z));

            //TRANSLATION LH
            Vector3 moveDirection_LH = leftController.forward * JetForce;
            Vector3 moveVector_LH = moveDirection_LH * axisVal_LH.y * axisVal_LH.y * axisVal_LH.y * axisVal_LH.y * axisVal_LH.y;

            Vector3 moveDirection_RH = rightController.forward * JetForce;//   head.forward * JetForce;
            Vector3 moveSideways_RH  = rightController.right * JetForce;

            Vector3 moveVector_RH = moveDirection_RH * axisVal_RH.y * axisVal_RH.y * axisVal_RH.y * axisVal_RH.y * axisVal_RH.y
                         + moveSideways_RH * axisVal_RH.x * axisVal_RH.x * axisVal_RH.x * axisVal_RH.x * axisVal_RH.x;

            moveStack_LH[countDamp] = moveVector_LH;
            moveStack_RH[countDamp] = moveVector_RH;

            if (++countDamp >= dampFrameCount)
            {
                countDamp = 0;
            }
            accumVector_LH = Vector3.zero;
            for (int i = 0; i < dampFrameCount; i++)
            {
                accumVector_LH += moveStack_LH[i];
                accumVector_RH += moveStack_RH[i];
            }
            accumVector_LH /= dampFrameCount;
            accumVector_RH /= dampFrameCount;
            transform.position += (accumVector_LH * Time.deltaTime + accumVector_RH * Time.deltaTime);
        }
    }
}