public class SplinePoint { public Vector3 p; public Vector3 n; public Color col; public float lifeTime; public float currTime; public float nrmFade_Start; public float lenToPrev; public bool active = false; public void init(Vector3 p1, Vector3 n1, Color col1, float lifetime1, float nrmFade_Start1,float len) { p = p1; n = n1; col = col1; lifeTime = lifetime1; currTime = 0f; nrmFade_Start = nrmFade_Start1; lenToPrev = len; active = true; } } public class EquiDistPoints { public Vector3 p; public Vector3 n; public Color col = Color.white; } public class ArgosQuad //tracks VB list divided by 6 { public float lifeTime = 0f; public float currTime = 0f; public float fadeStart = 0f; public MeshDraft mdQuad; public bool bActive = false; public ArgosQuad() { mdQuad = new MeshDraft(); } public void initWithStamp(MeshDraft md) { mdQuad.Add(md); } } public class ArgosMeshDraft : MeshDraft { public Controller ArgosCtrl; public float segmentLen = 0.05f; 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 SplinePoint[] sPointPool; public EquiDistPoints[] equiPoints; public int qpCurrIdx = 0; public int qpLen = 0; private int spCurrIdx = 0; private int spLen = 0; MeshDraft mdScatch = new MeshDraft(); Mesh meshInternal = new Mesh(); public ArgosMeshDraft() : base() { } public void OnSegmentChanged(float val) { segmentLen = val; Debug.Log(val); } public void initPools(int poolCount) { ArgosController.OnSegmentLenChanged += OnSegmentChanged; quadPool = new ArgosQuad[poolCount]; sPointPool = new SplinePoint[poolCount]; equiPoints = new EquiDistPoints[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(); sPointPool[i] = new SplinePoint(); quadPool[i].initWithStamp(mdScatch); } qpCurrIdx = spCurrIdx = 0; qpLen = spLen = poolCount; } public void Spline_Point_Paint(Vector3 p, Vector3 n, Color col, float lifetime, float nrmFade_Start) { Vector3 v = sPointPool[spCurrIdx].p; v = p - v; if (++spCurrIdx > spLen) spCurrIdx = 0; sPointPool[spCurrIdx].init(p, n, col, lifetime, nrmFade_Start, v.magnitude); } public Vector3 CatmullRom(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 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 Mesh ToMeshInternal_From_QuadPool() { Clear(); int poolCount = quadPool.Length; int v = 0;//verts int t = 0;//tris for (int i = 0; i < poolCount; i++) { if (quadPool[i].bActive) { Add(quadPool[i].mdQuad); } } return ToMeshInternal(); } 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); Init_Quad_fromPool(aq, v0, v1, v2, v3, col); } public void Init_Quad_fromPool(ArgosQuad aq, Vector3 vertex0, Vector3 vertex1, Vector3 vertex2, Vector3 vertex3, Color col)//TODO REOWKK QUADPOOL ONLY { Vector3 normal = Vector3.Cross((vertex1 - vertex0), (vertex2 - vertex0)).normalized; aq.mdQuad.vertices[0] = vertex0; aq.mdQuad.vertices[1] = vertex1; aq.mdQuad.vertices[2] = vertex2; aq.mdQuad.vertices[3] = vertex3; aq.mdQuad.normals[0] = normal; aq.mdQuad.normals[1] = normal; aq.mdQuad.normals[2] = normal; aq.mdQuad.normals[3] = normal; } private float getSampleLen() { float len = 0f; bool done = false; int i = spCurrIdx; int cnt = 0; while (!done) { len += sPointPool[i].lenToPrev; if (!sPointPool[i].active) done = true; if (++cnt == spLen) done = true; if (--i < 0) i = spLen; } return len; } private int prevScan(int scanIdx) { if (--scanIdx < 0) return spLen-1; else return scanIdx; } private int cmIdx(int scanIdx,int idx) { //0,2,3 if(idx == 0) { if (++scanIdx > spLen) return 0; else return scanIdx; } else if (idx == 2) return prevScan(scanIdx); else //if(idx == 3) { scanIdx -= 2; if (scanIdx < 0) return spLen + scanIdx; else return scanIdx; } } public void Spline_Frame() { PointFades(); float totLen = getSampleLen(); int segments = (int)(totLen / segmentLen); float deltLen = totLen / segments; float targetLen = 0f; float sampLen = sPointPool[spCurrIdx].lenToPrev; float sampLenNext = 0f; int cnt = 1; int scanIdx = prevScan(spCurrIdx); equiPoints[0].p = sPointPool[spCurrIdx].p; equiPoints[0].n = sPointPool[spCurrIdx].n; bool done = false; while(!done) { targetLen += deltLen; sampLen += sPointPool[scanIdx].lenToPrev; sampLenNext = sampLen = sPointPool[prevScan(scanIdx)].lenToPrev;//circ buff if(targetLen > sampLen & targetLen < sampLenNext) { float perc = (targetLen - sampLen) / (sampLenNext - sampLen); Vector3 p0 = sPointPool[cmIdx(scanIdx, 0)].p; Vector3 p1 = sPointPool[scanIdx].p; Vector3 p2 = sPointPool[cmIdx(scanIdx, 2)].p; Vector3 p3 = sPointPool[cmIdx(scanIdx, 3)].p; equiPoints[cnt].p = CatmullRom(perc, p0, p1, p2, p3); equiPoints[cnt].n = Vector3.Lerp(sPointPool[scanIdx].n,sPointPool[prevScan(scanIdx)].n,perc); equiPoints[cnt].col = sPointPool[scanIdx].col; if (++cnt >= segments || cnt >= spLen) done = true; } } } private void PointFades() { bool done = false; int i = spCurrIdx; int cnt = 0; while (!done) { sPointPool[i].currTime += Time.deltaTime; float fadeStart = sPointPool[i].nrmFade_Start * quadPool[i].lifeTime; if (sPointPool[i].currTime > fadeStart && sPointPool[i].active) { float attenAlpha = 1.0f - (sPointPool[i].currTime - fadeStart) / (sPointPool[i].lifeTime - fadeStart); Color col; col = sPointPool[i].col; col.a = attenAlpha; sPointPool[i].col = col; } if (sPointPool[i].currTime > sPointPool[i].lifeTime) { sPointPool[i].active = false; } if (++cnt == spLen) done = true; if (--i < 0) i = spLen; } } public void QuadPoolUpdate()//Change to Pool { int poolCount = quadPool.Length; for (int i = 0; i < poolCount; i++) { quadPool[i].currTime += Time.deltaTime; float fadeStart = quadPool[i].fadeStart * quadPool[i].lifeTime; if (quadPool[i].currTime > fadeStart && quadPool[i].bActive) { float attenAlpha = 1.0f - (quadPool[i].currTime - fadeStart) / (quadPool[i].lifeTime - fadeStart); Color col; for (int j = 0; j < 4; j++) { col = quadPool[i].mdQuad.colors[j]; col.a = attenAlpha; quadPool[i].mdQuad.colors[j] = col; } } if (quadPool[i].currTime > quadPool[i].lifeTime) { quadPool[i].bActive = false; //RemoveQuad(i); } } } public void Add_ITN_Node(MeshDraft tri, int sector, int nodePath, int ITG_idx) { Vector3 vC = (tri.vertices[0] + tri.vertices[1] + tri.vertices[2]) / 3f; ArgVert aV = new ArgVert(); aV.vPos = vC; aV.itn.sector = sector; aV.itn.nodePath = nodePath; aV.idx = ITG_idx; icoPointCloud.Add(aV); } public void SetSortDist(Vector3 Apex) { foreach (ArgVert aV in icoPointCloud) { aV.dist = (aV.vPos - Apex).magnitude; } } public void sortPointCloud() { icoPointCloud.Sort((x, y) => x.dist.CompareTo(y.dist)); } public void AddTriQual(MeshDraft tri) { Vector3 vC = (tri.vertices[0] + tri.vertices[1] + tri.vertices[2]) / 3f; int qual = TriQual.UNDEFINED; Add(tri); for (int i = 0; i < 3; i++)//Track the quality of the triangle UVs { vTriCenter.Add(vC); vQual.Add(qual); } }
Salk scientists discover REV-ERBα protein that controls strength of circadian rhythm