http://forum.notebookreview.com/threads/msi-gs60-ghost-tweak-information.761608/
using UnityEngine; using System.Collections; // Author: Eric Eastwood (ericeastwood.com) // // Description: // Written for this gd.se question: http://gamedev.stackexchange.com/a/75748/16587 // Simulates/Emulates pendulum motion in code // Works in any 3D direction and with any force/direciton of gravity // // Demonstration: https://i.imgur.com/vOQgFMe.gif // // Usage: https://i.imgur.com/BM52dbT.png public class Pendulum : MonoBehaviour { public GameObject Pivot; public GameObject Bob; public float mass = 1f; float ropeLength = 500f; public float dampFactor = 1f; Vector3 bobStartingPosition; bool bobStartingPositionSet = false; // You could define these in the `PendulumUpdate()` loop // But we want them in the class scope so we can draw gizmos `OnDrawGizmos()` public Vector3 vGravity; private Vector3 gravityDirection; private Vector3 tensionDirection; private Vector3 tangentDirection; private Vector3 pendulumSideDirection; private float tensionForce = 0f; private float gravityForce = 0f; // Keep track of the current velocity Vector3 currentVelocity = new Vector3(); // We use these to smooth between values in certain framerate situations in the `Update()` loop Vector3 currentStatePosition; Vector3 previousStatePosition; // Use this for initialization void Start() { // Set the starting position for later use in the context menu reset methods this.bobStartingPosition = this.Bob.transform.position; this.bobStartingPositionSet = true; this.PendulumInit(); } float t = 0f; float dt = 0.01f; float currentTime = 0f; float accumulator = 0f; void Update() { /* */ // Fixed deltaTime rendering at any speed with smoothing // Technique: http://gafferongames.com/game-physics/fix-your-timestep/ float frameTime = Time.time - currentTime; this.currentTime = Time.time; this.accumulator += frameTime; while (this.accumulator >= this.dt) { this.previousStatePosition = this.currentStatePosition; this.currentStatePosition = this.PendulumUpdate(this.currentStatePosition, this.dt); //integrate(state, this.t, this.dt); accumulator -= this.dt; this.t += this.dt; } float alpha = this.accumulator / this.dt; Vector3 newPosition = this.currentStatePosition * alpha + this.previousStatePosition * (1f - alpha); this.Bob.transform.position = newPosition; //this.currentStatePosition; /* */ //this.Bob.transform.position = this.PendulumUpdate(this.Bob.transform.position, Time.deltaTime); } // Use this to reset forces and go back to the starting position [ContextMenu("Reset Pendulum Position")] void ResetPendulumPosition() { if (this.bobStartingPositionSet) this.MoveBob(this.bobStartingPosition); else this.PendulumInit(); } // Use this to reset any built up forces [ContextMenu("Reset Pendulum Forces")] void ResetPendulumForces() { this.currentVelocity = Vector3.zero; // Set the transition state this.currentStatePosition = this.Bob.transform.position; } void PendulumInit() { // Get the initial rope length from how far away the bob is now this.ropeLength = Vector3.Distance(Pivot.transform.position, Bob.transform.position); this.ResetPendulumForces(); } void MoveBob(Vector3 resetBobPosition) { // Put the bob back in the place we first saw it at in `Start()` this.Bob.transform.position = resetBobPosition; // Set the transition state this.currentStatePosition = resetBobPosition; } Vector3 PendulumUpdate(Vector3 currentStatePosition, float deltaTime) { // Add gravity free fall this.gravityForce = this.mass * vGravity.magnitude; this.gravityDirection = vGravity.normalized; this.currentVelocity += this.gravityDirection * this.gravityForce * deltaTime; Vector3 pivot_p = this.Pivot.transform.position; Vector3 bob_p = this.currentStatePosition; Vector3 auxiliaryMovementDelta = this.currentVelocity * deltaTime; float distanceAfterGravity = Vector3.Distance(pivot_p, bob_p + auxiliaryMovementDelta); // If at the end of the rope if (distanceAfterGravity > this.ropeLength || Mathf.Approximately(distanceAfterGravity, this.ropeLength)) { this.tensionDirection = (pivot_p - bob_p).normalized; this.pendulumSideDirection = (Quaternion.Euler(0f, 90f, 0f) * this.tensionDirection); this.pendulumSideDirection.Scale(new Vector3(1f, 0f, 1f)); this.pendulumSideDirection.Normalize(); this.tangentDirection = (-1f * Vector3.Cross(this.tensionDirection, this.pendulumSideDirection)).normalized; float inclinationAngle = Vector3.Angle(bob_p - pivot_p, this.gravityDirection); this.tensionForce = this.mass * Physics.gravity.magnitude * Mathf.Cos(Mathf.Deg2Rad * inclinationAngle); float centripetalForce = ((this.mass * Mathf.Pow(this.currentVelocity.magnitude, 2)) / this.ropeLength); this.tensionForce += centripetalForce; this.currentVelocity += this.tensionDirection * this.tensionForce * deltaTime; this.currentVelocity = (1f - dampFactor/1000f) * this.currentVelocity; } // Get the movement delta Vector3 movementDelta = Vector3.zero; movementDelta += this.currentVelocity * deltaTime; //return currentStatePosition + movementDelta; float distance = Vector3.Distance(pivot_p, currentStatePosition + movementDelta); return this.GetPointOnLine(pivot_p, currentStatePosition + movementDelta, distance <= this.ropeLength ? distance : this.ropeLength); } Vector3 GetPointOnLine(Vector3 start, Vector3 end, float distanceFromStart) { return start + (distanceFromStart * Vector3.Normalize(end - start)); } void OnDrawGizmos() { // purple Gizmos.color = new Color(.5f, 0f, .5f); Gizmos.DrawWireSphere(this.Pivot.transform.position, this.ropeLength); Gizmos.DrawWireCube(this.bobStartingPosition, new Vector3(.5f, .5f, .5f)); // Blue: Auxilary Gizmos.color = new Color(.3f, .3f, 1f); // blue Vector3 auxVel = .3f * this.currentVelocity; Gizmos.DrawRay(this.Bob.transform.position, auxVel); Gizmos.DrawSphere(this.Bob.transform.position + auxVel, .2f); // Yellow: Gravity Gizmos.color = new Color(1f, 1f, .2f); Vector3 gravity = .3f * this.gravityForce * this.gravityDirection; Gizmos.DrawRay(this.Bob.transform.position, gravity); Gizmos.DrawSphere(this.Bob.transform.position + gravity, .2f); // Orange: Tension Gizmos.color = new Color(1f, .5f, .2f); // Orange Vector3 tension = .3f * this.tensionForce * this.tensionDirection; Gizmos.DrawRay(this.Bob.transform.position, tension); Gizmos.DrawSphere(this.Bob.transform.position + tension, .2f); // Red: Resultant Gizmos.color = new Color(1f, .3f, .3f); // red Vector3 resultant = gravity + tension; Gizmos.DrawRay(this.Bob.transform.position, resultant); Gizmos.DrawSphere(this.Bob.transform.position + resultant, .2f); /* * / // Green: Pendulum side direction Gizmos.color = new Color(.3f, 1f, .3f); Gizmos.DrawRay(this.Bob.transform.position, 3f*this.pendulumSideDirection); Gizmos.DrawSphere(this.Bob.transform.position + 3f*this.pendulumSideDirection, .2f); /* */ /* * / // Cyan: tangent direction Gizmos.color = new Color(.2f, 1f, 1f); // cyan Gizmos.DrawRay(this.Bob.transform.position, 3f*this.tangentDirection); Gizmos.DrawSphere(this.Bob.transform.position + 3f*this.tangentDirection, .2f); /* */ } }
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(); } } }