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;
}
}


