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; } } 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); } } public void AddHex(MeshDraft tri)//from triangle see: http://argos.vu/wp-content/uploads/2016/04/HCs-1.png { Vector3 HC = (tri.vertices[0] + tri.vertices[1] + tri.vertices[2]) / 3f; Vector3 H0 = (tri.vertices[1] + tri.vertices[0]) / 2f; Vector3 H1 = (tri.vertices[1] + HC) / 2f; Vector3 H2 = (tri.vertices[2] + tri.vertices[1]) / 2f; Vector3 H3 = (tri.vertices[2] + HC) / 2f; Vector3 H4 = (tri.vertices[0] + tri.vertices[2]) / 2f; Vector3 H5 = (tri.vertices[0] + HC) / 2f; List<Vector3> vL = new List<Vector3>(8) { HC, H0, H1, H2, H3, H4, H5, H0 }; List<Vector2> uvMapL = new List<Vector2>(8) { new Vector2(0.5f, 0.5f), new Vector2(0.5f, 1f), new Vector2(1, 0.75f), new Vector2(1, 0.25f), new Vector2(0.5f, 0), new Vector2(0, 0.25f), new Vector2(0, 0.75f), new Vector2(0.5f, 1f) }; Add(HexFan(vL, uvMapL)); } public void AddTriQual(MeshDraft tri, int qual) { Vector3 vC = (tri.vertices[0] + tri.vertices[1] + tri.vertices[2]) / 3f; Add(tri); for (int i = 0; i < 3; i++)//Track the quality of the triangle UVs { vTriCenter.Add(vC); vQual.Add(qual); } } } }
Argos_Engine_Foundry – Sound_Paint 1
Shader "Custom/NegativeGrayscale" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _TouchX ("TouchX", Float) = 0.0 _TouchY ("TouchY", Float) = 0.0 } SubShader { Pass{ CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" sampler2D _MainTex; float _TouchX; float _TouchY; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; float4 _MainTex_ST; v2f vert (appdata_base v) { v2f o; o.pos = mul (UNITY_MATRIX_MVP, v.vertex); float distance; float2 direction; float2 _Touch; // take into account homogeneous coordinate! float2 viewPos = (o.pos.xy/o.pos.w); float sinDistance; _Touch.x=_TouchX; _Touch.y=_TouchY; direction =viewPos.xy-_Touch; distance=sqrt(direction.x*direction.x+direction.y*direction.y); sinDistance = (sin(distance)+1.0); direction=direction/distance; if ((sinDistance>0.0)&&(_Touch.x != 2.0)) { viewPos.xy+=(direction*(0.3/sinDistance)); o.pos.xy = (viewPos.xy*o.pos.w); } o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); return o; } half4 frag(v2f i) : COLOR { half4 c = tex2D (_MainTex, i.uv); half color = 1.0 - ((c.r + c.g + c.b)/3); c.r = color; c.g = color; c.b = color; return c; } ENDCG } } FallBack "Diffuse" }
using UnityEngine; using System; using Vuforia; /// <summary> /// This script sets up the background shader effect and contains the logic /// to capture longer touch "drag" events that distort the video background. /// </summary> public class NegativeGrayscaleEffect : MonoBehaviour { #region MONOBEHAVIOUR_METHODS void Update() { float touchX = 2.0f; float touchY = 2.0f; if (Input.GetMouseButton(0)) { Vector2 touchPos = Input.mousePosition; // Adjust the touch point for the current orientation touchX = ((touchPos.x / Screen.width) - 0.5f) * 2.0f; touchY = ((touchPos.y / Screen.height) - 0.5f) * 2.0f; } // Pass the touch coordinates to the shader Material mat = GetComponent<Renderer>().material; mat.SetFloat("_TouchX", touchX); mat.SetFloat("_TouchY", touchY); } #endregion //MONOBEHAVIOUR_METHODS }