using UnityEngine; using System.Collections; using System.Collections.Generic; using UnityEngine.UI; public class ARGOS_12HORNS : MonoBehaviour { //The following Cartesian coordinates define the vertices //of an icosahedron with edge-length 2, //centered at the origin: //(0, ±1, ±φ) //(±1, ±φ, 0) //(±φ, 0, ±1) static float Phi = (Mathf.Sqrt(5f) + 1f)/2f; public UI_Control ui; public Vector3[] v12HORNS = new Vector3[] { new Vector3(0, 1f, Phi), new Vector3(0, -1f, Phi), new Vector3(-Phi, 0, 1), new Vector3(Phi, 0, 1f), new Vector3(1f, Phi,0), new Vector3(1f, -Phi,0), new Vector3(-1f, Phi,0), new Vector3(-1f, -Phi, 0), new Vector3(0, 1f, -Phi), new Vector3(0, -1f, -Phi), new Vector3(-Phi, 0, -1f), new Vector3(Phi, 0, -1f) }; public GameObject NavSphereWindowPrefab; bool isOn_HeadUpDisplay = false; public Button LockNavSphereButt; public Button RotateNavSphereButt; public List<Vector3> v12HORN_Norms = new List<Vector3>(); List<GameObject> goCircs = new List<GameObject>(); public float minLen = 0.01f; public float radius = 5f; float tAccum = 0f; List<Vector3> vList = new List<Vector3>(); Vector3 vLast = Vector3.zero; float tLast = 0f; float lastAngle; public GameObject psRiderPreFab; GameObject psRiderInst; PS_Rider psRider; Phasor phasor_0; int[] Color_12_RGB = { 0xffff00, 0xffc700, 0xff9100, 0xff6301, 0xff0000, 0xc6037e, 0x713697, 0x713697, 0x444ea1, 0x2772b2, 0x2772b2, 0x008e5b, 0x008e5b, 0x8ac819, }; Color fromRGB(int col, float alpha) { Color c; c.r = ((float)((col & 0xff0000) >> 16)) / 256f; c.g = ((float)((col & 0x00ff00) >> 8)) / 256f; c.b = ((float)((col & 0x0000ff))) / 256f; c.a = alpha; return c; } void Start () { float mag = v12HORNS[0].magnitude; for (int i = 0; i < 12; i++) v12HORN_Norms.Add(v12HORNS[i] / mag); ui = GameObject.Find("UI_Control_Canvas").GetComponent<UI_Control>(); float alpha; Quaternion q; for(int i = 0; i<12; i++) { q = Quaternion.LookRotation(v12HORNS[i]); goCircs.Add((GameObject)Instantiate(NavSphereWindowPrefab, v12HORNS[i], q)); goCircs[i].gameObject.transform.SetParent(transform); goCircs[i].transform.localScale = new Vector3(12.34f, 12.34f, 12.34f); goCircs[i].GetComponentInChildren<Phasor>().freq = ui.arrow_freq; goCircs[i].GetComponentInChildren<Canvas>().GetComponentInChildren<Text>().text = i.ToString(); alpha = goCircs[i].GetComponentInChildren<Canvas>().GetComponentInChildren<Text>().color.a; goCircs[i].GetComponentInChildren<Canvas>().GetComponentInChildren<Text>().color = fromRGB(Color_12_RGB[i], alpha); alpha = goCircs[i].GetComponent<Renderer>().material.color.a; goCircs[i].GetComponent<Renderer>().material.color = fromRGB(Color_12_RGB[i], alpha); goCircs[i].gameObject.SetActive(isOn_HeadUpDisplay); } GetComponent<MeshRenderer>().enabled = isOn_HeadUpDisplay; LockNavSphereButt.gameObject.SetActive(isOn_HeadUpDisplay); RotateNavSphereButt.gameObject.SetActive(isOn_HeadUpDisplay); InitTestPainting(); } void InitTestPainting() { psRiderInst = (GameObject)Instantiate(psRiderPreFab, Vector3.zero, Quaternion.identity); psRider = psRiderInst.GetComponent<PS_Rider>(); phasor_0 = goCircs[0].GetComponentInChildren<Phasor>(); } float phasorUpdate() { float angle = (360f * ui.arrow_freq*tAccum); phasor_0.transform.localRotation = Quaternion.Euler(0f, 0f, angle); return angle; } void phasorSubFrame(float angle) { phasor_0.transform.localRotation = Quaternion.Euler(0f, 0f, angle); } int frameCounter = 0; void Update () { tAccum += Time.deltaTime; frameCounter++; if (frameCounter % 120 == 0) System.GC.Collect(); float currAngle = phasorUpdate(); Vector3 vCurr = Func(tAccum); vCurr.Normalize(); vCurr *= radius; Vector3 vPointing = vCurr - vLast; vList.Clear(); if(vPointing.magnitude > minLen) { float numSegs = vPointing.magnitude / minLen; if (numSegs > 10) numSegs = 10f; float t = tLast; float delt = (tAccum - tLast) / numSegs; float angle = lastAngle; float deltThet = (currAngle - lastAngle) / numSegs; for(int i = 0; i<numSegs;i++) { phasorSubFrame(angle); vCurr = Func(t); vCurr.Normalize(); vCurr *= radius; vList.Add(vCurr); t += delt; angle += deltThet; } } psRider.paintList(vList,ui.duration,ui.line_width,ui.fade_start); tLast = tAccum; vLast = vCurr; lastAngle = currAngle; } Vector3 Func(float t) { return v12HORNS[0] + phasor_0.transform.right * ui.phasor_len * ((1f - ui.ab_ratio) + ui.ab_ratio * Mathf.Sin(2f * Mathf.PI * t * ui.brush_freq)); } public void onDisplayICO_Button() { isOn_HeadUpDisplay = !isOn_HeadUpDisplay; for(int i = 0; i<12; i++) { goCircs[i].gameObject.SetActive(isOn_HeadUpDisplay); } GetComponent<MeshRenderer>().enabled = isOn_HeadUpDisplay; LockNavSphereButt.gameObject.SetActive(isOn_HeadUpDisplay); RotateNavSphereButt.gameObject.SetActive(isOn_HeadUpDisplay); } }
public class ArgosQuad //tracks VB list divided by 6 { public float lifeTime = 0f; public float currTime = 0f; public float fadeStart = 0f; public Vector3[] vertices = new Vector3[4]; public int[] triangles = new int[6]; public Vector3[] normals = new Vector3[4]; public Vector2[] uv = new Vector2[4]; public Color[] colors = new Color[4]; public bool bActive = false; public ArgosQuad() { } public void initWithStamp(MeshDraft md) { for(int i = 0; i<4; i++) { uv[i] = md.uv[i]; colors[i] = md.colors[i]; triangles[i] = md.triangles[i]; } triangles[4] = md.triangles[4]; triangles[5] = md.triangles[5]; } } public class ArgosMeshDraft : MeshDraft { public List<Vector3> vTriCenter = new List<Vector3>(); public List<int> vQual = new List<int>(); public List<ArgVert> icoPointCloud = new List<ArgVert>(); public List<ArgosQuad> quadLst = new List<ArgosQuad>(); public ArgosQuad[] quadPool; public int qpCurrIdx = 0; public int qpLen = 0; MeshDraft mdScatch = new MeshDraft(); Mesh meshInternal = new Mesh(); public ArgosMeshDraft() : base() { } public void initQuadPool(int poolCount) { quadPool = new ArgosQuad[poolCount]; Color col = new Color(1, 1, 1, 1); mdScatch.Add(Quad(Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero,col)); for (int i = 0; i < poolCount; i++) { quadPool[i] = new ArgosQuad(); quadPool[i].initWithStamp(mdScatch); } qpCurrIdx = 0; qpLen = poolCount; } public ArgosQuad getPoolQuad() { bool scan = true; int idx = qpCurrIdx; int cnt = 0; while (scan) { cnt++; if (quadPool[idx].bActive == false) { quadPool[idx].bActive = true; qpCurrIdx = idx; return quadPool[idx]; } if(++idx > qpLen-1) { idx = 0; } if(cnt > qpLen) { scan = false; } } return null; } public Mesh ToMeshInternal() { meshInternal.Clear(); meshInternal.vertices = vertices.ToArray(); meshInternal.triangles = triangles.ToArray(); meshInternal.normals = normals.ToArray(); meshInternal.uv = uv.ToArray(); meshInternal.colors = colors.ToArray(); return meshInternal; } public void Quad_Paint(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3, Color col, float lifetime, float fade_start) { ArgosQuad aq = getPoolQuad(); if (aq == null) return;//no non active quads aq.lifeTime = lifetime; aq.fadeStart = fade_start; aq.currTime = 0f; quadLst.Add(aq); Add(Quad_fromPool(aq, v0, v1, v2, v3, col)); } public MeshDraft Quad_fromPool(ArgosQuad aq, Vector3 vertex0, Vector3 vertex1, Vector3 vertex2, Vector3 vertex3, Color col) { Vector3 normal = Vector3.Cross((vertex1 - vertex0), (vertex2 - vertex0)).normalized; mdScatch.vertices[0] = aq.vertices[0] = vertex0; mdScatch.vertices[1] = aq.vertices[1] = vertex1; mdScatch.vertices[2] = aq.vertices[2] = vertex2; mdScatch.vertices[3] = aq.vertices[3] = vertex3; mdScatch.normals[0] = aq.normals[0] = normal; mdScatch.normals[1] = aq.normals[1] = normal; mdScatch.normals[2] = aq.normals[2] = normal; mdScatch.normals[3] = aq.normals[3] = normal; for (int i = 0; i < 4; i++) { mdScatch.uv[i] = aq.uv[i]; mdScatch.colors[i] = aq.colors[i]; mdScatch.triangles[i] = aq.triangles[i]; } mdScatch.triangles[4] = aq.triangles[4]; mdScatch.triangles[5] = aq.triangles[5]; return mdScatch; } public void QuadListUpdate() { for(int i = 0; i<quadLst.Count; i++) { quadLst[i].currTime += Time.deltaTime; float fadeStart = quadLst[i].fadeStart * quadLst[i].lifeTime; if (quadLst[i].currTime > fadeStart) { float attenAlpha = 1.0f - (quadLst[i].currTime - fadeStart) / (quadLst[i].lifeTime - fadeStart); Color col; for (int j = 0; j < 4; j++) { col = colors[4 * i + j]; col.a = attenAlpha; colors[4 * i + j] = col; } } if (quadLst[i].currTime > quadLst[i].lifeTime) { quadLst[i].bActive = false; RemoveQuad(i); } } } public void RemoveQuad(int i) { quadLst.RemoveAt(i); vertices.RemoveRange(i * 4, 4); uv.RemoveRange(i * 4, 4); colors.RemoveRange(i * 4, 4); normals.RemoveRange(i * 4, 4); triangles.RemoveRange(i * 6, 6); for (int j = i * 6; j < triangles.Count; j++) { triangles[j] -= 4; } }