using UnityEngine;
using System;
using System.Collections;
using ProceduralToolkit;
using System.Collections.Generic;
namespace ProceduralToolkit
{
public static class TriQual
{
public const int A = 0;
public const int B = 1;
public const int C = 2;
public const int D = 3;
public const int E = 4;
public const int F = 5;
public const int G = 6;
public const int H = 7;
public const int I = 8;
public const int J = 9;
public const int K = 10;
public const int L = 11;
public const int M = 12;
public const int N = 13;
public const int O = 14;
public const int P = 15;
public const int Q = 16;
public const int R = 17;
public const int S = 18;
public const int UNDEFINED = int.MaxValue;
}
public class ICO_Tree_Node_ID
{
public int sector; // 20 sectors to ICO
public int nodePath; // 2 bits per depth level
}
public class ArgVert
{
public Vector3 vPos;
public ICO_Tree_Node_ID itn = new ICO_Tree_Node_ID();
public float dist;
public Vector3 vForce; //constrain position to sphere radius
public Vector3 vVel;
public float maxDistToNeighbor = 0;
public float minDistToNeighbor = float.MaxValue;
public int idx;
public class NB
{
public ArgVert aV;
public float distFrom;
public NB()
{
aV = null;
distFrom = float.MaxValue;
}
}
public List<NB> avNeigbor = new List<NB>();
public ArgVert()
{
for (int i = 0; i < 6; i++)
{
avNeigbor.Add(new NB());
avNeigbor[i].aV = this;
}
vPos = new Vector3();
}
public float getMaxDistToNeighbor()
{
maxDistToNeighbor = 0;
for (int i = 0; i < 6; i++)
{
if (avNeigbor[i].distFrom > maxDistToNeighbor)
{
maxDistToNeighbor = avNeigbor[i].distFrom;
}
}
return maxDistToNeighbor;
}
public float getMinDistToNeighbor()
{
minDistToNeighbor = float.MaxValue;
for (int i = 0; i < 6; i++)
{
if (avNeigbor[i].distFrom < minDistToNeighbor)
{
minDistToNeighbor = avNeigbor[i].distFrom;
}
}
return minDistToNeighbor;
}
public bool isAVinNeighborList(ArgVert aV)
{
for (int i = 0; i < 6; i++)
{
if (avNeigbor[i].aV == aV) return true;
}
return false;
}
public int isLessThan(float dist)
{
for (int i = 0; i < 6; i++)
{
if (dist < avNeigbor[i].distFrom) return i;
}
return -1;
}
public bool goesHere(int i, float dist, ArgVert aV_Contender)
{
if (dist < avNeigbor[i].distFrom)
{
NB nb = new NB();
nb.aV = aV_Contender;
nb.distFrom = dist;
nb.aV.idx = aV_Contender.idx;
avNeigbor.Insert(i, nb);
avNeigbor.RemoveAt(6);
return true;
}
return false;
}
public void insNeighbor_One_Shot(float dist, ArgVert aV_Contender)
{
for (int i = 0; i < 6; i++)
{
if (goesHere(i, dist, aV_Contender)) return;
}
}
}
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 ArgosMeshDraft() : base()
{
}
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);
}
}
}
}
Convert to ArgosMesh
using UnityEngine;
using System.Collections;
using ProceduralToolkit;
using UnityEngine.UI;
public class PaintElement : MonoBehaviour {
Mesh mesh;
private MeshDraft mDraft;
public MeshDraft Mdraft
{
get { return mDraft; }
}
void Start ()
{
MeshFilter mf = GetComponent<MeshFilter>();
if (mf.mesh == null)
mf.mesh = new Mesh();
mesh = mf.mesh;
mDraft = new MeshDraft();
}
void Update ()
{
}
public int GetNumVertices()
{
return mDraft.vertices.Count;
}
public Vector3 GetVertex(int i)
{
return mDraft.vertices[i];
}
public void SetVertex(int i, Vector3 v)
{
mDraft.vertices[i] = v;
}
public void MeshDraft_ToMesh()
{
if (mDraft != null)
{
GetComponent<MeshFilter>().mesh = mDraft.ToMesh();
}
}
public void initAddMeshDraft(MeshDraft md)
{
MeshFilter mf = GetComponent<MeshFilter>();
if (mf.mesh == null)
mf.mesh = new Mesh();
mesh = mf.mesh;
mDraft = new MeshDraft();
if (mDraft != null)
{
mDraft.Add(md);
GetComponent<MeshFilter>().mesh = mDraft.ToMesh();
}
}
public void AddMeshDraft(MeshDraft md)
{
if (mDraft != null)
{
mDraft.Add(md);
GetComponent<MeshFilter>().mesh = mDraft.ToMesh();
}
}
public void AddMeshDraft_Only(MeshDraft md)
{
if (mDraft != null)
{
mDraft.Add(md);
}
}
public void AddQuad(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3)
{
if (mDraft != null)
{
mDraft.Add(MeshDraft.Quad(v0, v1, v2, v3));
GetComponent<MeshFilter>().mesh = mDraft.ToMesh();
}
}
public void AddQuad(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3, Color col)
{
if (mDraft != null)
{
mDraft.Add(MeshDraft.Quad(v0, v1, v2, v3, col));
GetComponent<MeshFilter>().mesh = mDraft.ToMesh();
//mesh.RecalculateBounds();
}
}
}

Diagram argos_NavSphere structure
SubFrame Tweening needed:
UNITY Script Execution
All Awake calls
All Start Calls
while (stepping towards variable delta time)
All FixedUpdate functions
Physics simulation
OnEnter/Exit/Stay trigger functions
OnEnter/Exit/Stay collision functions
Rigidbody interpolation applies transform.position and rotation
OnMouseDown/OnMouseUp etc. events
All Update functions




