https://youtu.be/GaAjve4NZd0
Hang a rope from one controller with large Mass at the end – Can you get it to Orbit through Angular Momentum?
Collision – Performance – Expect Hit
using UnityEngine; using System.Collections; using ProceduralToolkit; using UnityEngine.UI; using System.Collections.Generic; using System.Runtime.Serialization; using VRTK; using System; [System.Serializable] public class SerialVect3 { public SerialVect3(Vector3 vIn) { _vx = vIn.x; _vy = vIn.y; _vz = vIn.z; } public float _vx; public float _vy; public float _vz; } public class Argos_Hex_Brush : MonoBehaviour { Mesh mesh; [SerializeField] Material _material; public VRTK_ControllerEvents ctrl_events; public AnimationCurve scaleCurve; //let's say you edit from inspector, but you can built at runtime if you prefer MaterialPropertyBlock _block; public GameObject newHex_Loc_Prefab; private ArgosMeshDraft amDraft; public ArgosMeshDraft AmDraft { get { return amDraft; } } public ArgosSphere_Indexing argosSphere; private int lastHexIdx = -1; public Color color; public Text dbgTex; private UI_Control ui_Control; List<Vector3> CatmullRom_Point_List = new List<Vector3>(); [SerializeField] public List<SerialVect3> Equi_Distant_Points = new List<SerialVect3>(); private Vector3 vLast_Point; private Vector3 vCursPos; private Vector3 vUp_Last; void Start () { MeshFilter mf = GetComponent<MeshFilter>(); if (mf.mesh == null) mf.mesh = new Mesh(); mesh = mf.mesh; amDraft = new ArgosMeshDraft(); _block = new MaterialPropertyBlock(); amDraft.initQuadPool_AnimationCurve(5000, scaleCurve); ui_Control = GameObject.Find("UI_Control_Canvas").GetComponent < UI_Control>(); ctrl_events.TriggerPressed += new ControllerInteractionEventHandler(Triggr_StartCollectingPoints); ctrl_events.TriggerReleased += new ControllerInteractionEventHandler(Triggr_StopCollectingPoints); } public void SetCursPos(Vector3 vPos) { vCursPos = vPos; } public void Triggr_StartCollectingPoints(object sender, ControllerInteractionEventArgs e) { vLast_Point = vCursPos; CatmullRom_Point_List.Clear(); CatmullRom_Point_List.Add(vCursPos); } public void Triggr_StopCollectingPoints(object sender, ControllerInteractionEventArgs e) { } float accumTime = 0f; void Update () { accumTime += Time.deltaTime; amDraft.QuadListUpdate(); GetComponent<MeshFilter>().mesh = amDraft.ToMeshInternal();// //Vector3 vH0 = a12horns.v12HORN_Norms[0]; Quaternion q; //for (int i = 0; i < 12; i++) //{ //q = Quaternion.FromToRotation(vH0, a12horns.v12HORN_Norms[i]); q = Quaternion.identity; //print(q.ToString()); Graphics.DrawMesh(GetComponent<MeshFilter>().mesh, Vector3.zero, q, _material, gameObject.layer, null, 0, _block); //} } public int GetNumVertices() { return amDraft.vertices.Count; } public Vector3 GetVertex(int i) { return amDraft.vertices[i]; } public void SetVertex(int i, Vector3 v) { amDraft.vertices[i] = v; } public void MeshDraft_ToMesh() { if (amDraft != null) { GetComponent<MeshFilter>().mesh = amDraft.ToMesh(); } } public void initAddMeshDraft(MeshDraft md) { MeshFilter mf = GetComponent<MeshFilter>(); if (mf.mesh == null) mf.mesh = new Mesh(); mesh = mf.mesh; amDraft = new ArgosMeshDraft(); if (amDraft != null) { amDraft.Add(md); GetComponent<MeshFilter>().mesh = amDraft.ToMesh(); } } public void Paint(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3, Color col, float duration, float fade_start) { if (amDraft != null) { amDraft.Quad_Paint(v0, v1, v2, v3, col, duration, fade_start); } } public void PaintHex(Vector3 pos, Vector3 vOffset, float lineWidth) { float pointDist = lineWidth * 8f; Vector3 vDiff = pos - vLast_Point; if (vDiff.magnitude > pointDist) { CatmullAdd(pos + vOffset,lineWidth); vLast_Point = pos; } int newIdx = argosSphere.getHexIdx(pos); dbgTex.text = "CM DIST = " + pointDist.ToString("F3"); if(newIdx != lastHexIdx && newIdx != -1) { List<Vector3> vL = argosSphere.HexQuads[newIdx].mdH.vertices; Paint(vL[0] + vOffset, vL[1] + vOffset, vL[3] + vOffset, vL[2] + vOffset, color, 0.1f, 0.7f); lastHexIdx = newIdx; } } public void CatmullAdd(Vector3 pos,float lineWidth) { Vector3 vUp; Vector3 vc12; Vector3 vcIn; //break by 8 for music CatmullRom_Point_List.Add(pos); Instantiate(newHex_Loc_Prefab, pos, Quaternion.identity); if(CatmullRom_Point_List.Count > 3) { Vector3[] splinePoints = new Vector3[8]; int cmc = CatmullRom_Point_List.Count - 1; for (int i = 0; i<8; i++) { splinePoints[i] = ReturnCatmullRom((float)i / 8f, CatmullRom_Point_List[cmc - 3], CatmullRom_Point_List[cmc - 2], CatmullRom_Point_List[cmc - 1], CatmullRom_Point_List[cmc]); SerialVect3 sv3 = new SerialVect3(splinePoints[i]); Equi_Distant_Points.Add(sv3);//add points to serialized equidistant Vector3s } if (CatmullRom_Point_List.Count == 4) { vc12 = CatmullRom_Point_List[cmc - 1] - CatmullRom_Point_List[cmc - 2]; vcIn = CatmullRom_Point_List[cmc - 2] - argosSphere.transform.position; vc12.Normalize(); vcIn.Normalize(); vUp_Last = Vector3.Cross(vcIn, vc12); vUp_Last.Normalize(); } Vector3[] verts = new Vector3[4]; for (int j = 0; j<7;j++) { Vector3 v12 = splinePoints[j + 1] - splinePoints[j]; Vector3 vIn = splinePoints[j + 1] - argosSphere.transform.position; vIn.Normalize(); v12.Normalize(); vUp = Vector3.Cross(vIn, v12); vUp.Normalize(); verts[0] = splinePoints[j] - vUp_Last * lineWidth / 2f; verts[1] = splinePoints[j] + vUp_Last * lineWidth / 2f; verts[2] = splinePoints[j+1] + vUp * lineWidth / 2f; verts[3] = splinePoints[j+1] - vUp * lineWidth / 2f; Paint(verts[0], verts[1], verts[2], verts[3], color, 30f, 0.7f); vUp_Last = vUp; } vc12 = CatmullRom_Point_List[cmc-1] - splinePoints[6]; vcIn = CatmullRom_Point_List[cmc - 1] - argosSphere.transform.position; vc12.Normalize(); vcIn.Normalize(); vUp = Vector3.Cross(vcIn, vc12); vUp.Normalize(); verts[0] = splinePoints[7] - vUp_Last * lineWidth / 2f; verts[1] = splinePoints[7] + vUp_Last * lineWidth / 2f; verts[2] = CatmullRom_Point_List[cmc - 1] + vUp * lineWidth / 2f; verts[3] = CatmullRom_Point_List[cmc - 1] - vUp * lineWidth / 2f; Paint(verts[0], verts[1], verts[2], verts[3], color, 30f, 0.7f); vUp_Last = vUp; } } //Returns a position between 4 Vector3 with Catmull-Rom Spline algorithm //http://www.iquilezles.org/www/articles/minispline/minispline.htm Vector3 ReturnCatmullRom(float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3) { Vector3 a = 0.5f * (2f * p1); Vector3 b = 0.5f * (p2 - p0); Vector3 c = 0.5f * (2f * p0 - 5f * p1 + 4f * p2 - p3); Vector3 d = 0.5f * (-p0 + 3f * p1 - 3f * p2 + p3); Vector3 pos = a + (b * t) + (c * t * t) + (d * t * t * t); return pos; } public void AddMeshDraft(MeshDraft md) { if (amDraft != null) { amDraft.Add(md); GetComponent<MeshFilter>().mesh = amDraft.ToMesh(); } } public void AddMeshDraft_Only(MeshDraft md) { if (amDraft != null) { amDraft.Add(md); } } public void AddQuad(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3) { if (amDraft != null) { amDraft.Add(MeshDraft.Quad(v0, v1, v2, v3)); GetComponent<MeshFilter>().mesh = amDraft.ToMesh(); } } public void AddQuad(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3, Color col) { if (amDraft != null) { amDraft.Add(MeshDraft.Quad(v0, v1, v2, v3, col)); GetComponent<MeshFilter>().mesh = amDraft.ToMesh(); } } }
using UnityEngine; using System; using System.IO; using System.Runtime.Serialization.Formatters.Binary; using UnityEngine.UI; using System.Collections.Generic; /// <summary> /// Class that handles the application data. /// </summary> public class Serialize : MonoBehaviour { [Serializable] public class UserData { public float rQuadDist; public float rCamDist; public float uiDist; public float echo_gain; public float echo_time; public float delay_delta; public float echo_attenuation; } static UserData URD;//USER READ DATA static UserData USD;//USER SAVE DATA private HMD_Ctrl_Tracking hmd_Ctrl_Tracking; public Slider rQuadDistSlider; public Slider rCamDistSlider; public Slider uiDistSlider; public Slider echo_gainSlider; public Slider echo_timeSlider; public Slider delay_deltaSlider; public Slider echo_attenuationSlider; StreamWriter sWrite; StreamWriter sRead; void Start() { URD = new UserData(); USD = new UserData(); sWrite = new StreamWriter("Test_Save_Pdata.txt"); sRead = new StreamWriter("Test_Read_Pdata.txt"); LoadSettings(); print("rQuadDist = " + URD.rQuadDist.ToString("F3")); print("rCamDist = " + URD.rCamDist.ToString("F3")); hmd_Ctrl_Tracking = transform.parent.gameObject.GetComponent<HMD_Ctrl_Tracking>(); } public void LoadSettings() { LoadFile("ArgosData"); SetUserPrefs(); } public void SaveCurrentSettings() { USD.rQuadDist = rQuadDistSlider.value; USD.rCamDist = rCamDistSlider.value; USD.uiDist = uiDistSlider.value; USD.echo_gain = echo_gainSlider.value; USD.echo_time= echo_timeSlider.value; USD.delay_delta = delay_deltaSlider.value; USD.echo_attenuation = echo_attenuationSlider.value; SaveFile("ArgosData", USD); } public void OnApplicationQuit() { sWrite.Close(); sRead.Close(); SaveCurrentSettings(); } private void SetUserPrefs() { rQuadDistSlider.value = URD.rQuadDist; rCamDistSlider.value = URD.rCamDist; uiDistSlider.value = URD.uiDist; echo_gainSlider.value = URD.echo_gain; echo_timeSlider.value = URD.echo_time; delay_deltaSlider.value = URD.delay_delta; echo_attenuationSlider.value = URD.echo_attenuation; } private static UserData UserData_Defaults() { UserData NewUD = new UserData(); NewUD.rQuadDist = 70f; NewUD.rCamDist = 2500f; NewUD.uiDist = 70f; NewUD.echo_gain = 0.42f; NewUD.echo_time = 1.54f; NewUD.delay_delta = -0.37f; NewUD.echo_attenuation = 0.65f; return NewUD; } public void SavePlist(List<SerialVect3> pList) { for(int i = 0; i<pList.Count;i++) { sWrite.WriteLine(i.ToString() + " Vect3(" + pList[i]._vx.ToString("F3") + ", " + pList[i]._vy.ToString("F3") + ", " + pList[i]._vz.ToString("F3") + "),"); } Save_PList("plist.dat", pList); } public List<SerialVect3> LoadPlist() { List<SerialVect3> pList; pList = Load_PList("plist.dat"); for (int i = 0; i < pList.Count; i++) { sRead.WriteLine(i.ToString() + " Vect3(" + pList[i]._vx.ToString("F3") + ", " + pList[i]._vy.ToString("F3") + ", " + pList[i]._vz.ToString("F3") + "),"); } return pList; } private static void SaveFile(string filename, UserData obj) { try { filename = Application.persistentDataPath + Path.DirectorySeparatorChar + filename; Stream fileStream = File.Open(filename, FileMode.Create, FileAccess.Write); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(fileStream, obj); fileStream.Close(); } catch (Exception e) { Debug.LogWarning("Save.SaveFile(): Failed to serialize object to a file " + filename + " (Reason: " + e.Message + ")"); } } private static UserData LoadFile(string filename) { filename = Application.persistentDataPath + Path.DirectorySeparatorChar + filename; if (File.Exists(filename)) { try { Stream fileStream = File.Open(filename, FileMode.Open, FileAccess.Read); BinaryFormatter formatter = new BinaryFormatter(); URD = (UserData)formatter.Deserialize(fileStream); fileStream.Close(); return URD; } catch (Exception e) { Debug.LogWarning("LoadFile(): Failed to deserialize a file " + filename + " (Reason: " + e.Message + ")"); return UserData_Defaults(); } } else { URD = UserData_Defaults(); SaveFile(filename, URD); return URD; } } private static void Save_PList(string filename, List<SerialVect3> pList) { try { //filename = Application.persistentDataPath + Path.DirectorySeparatorChar + filename; Stream fileStream = File.Open(filename, FileMode.Create, FileAccess.Write); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(fileStream, pList); fileStream.Close(); } catch (Exception e) { Debug.LogWarning("Save.SaveFile(): Failed to serialize object to a file " + filename + " (Reason: " + e.Message + ")"); } } private static List<SerialVect3> Load_PList(string filename) { //filename = Application.persistentDataPath + Path.DirectorySeparatorChar + filename; List<SerialVect3> pList = new List<SerialVect3>(); if (File.Exists(filename)) { try { Stream fileStream = File.Open(filename, FileMode.Open, FileAccess.Read); BinaryFormatter formatter = new BinaryFormatter(); pList = (List<SerialVect3>)formatter.Deserialize(fileStream); fileStream.Close(); return pList; } catch (Exception e) { Debug.LogWarning("Load_PList(): Failed to deserialize pLIST " + filename + " (Reason: " + e.Message + ")"); return null; } } else { return null; } } }
Hang a rope from one controller with large Mass at the end – Can you get it to Orbit through Angular Momentum?