in Cosahedra.cs
public void OnStopButtonDown() { bSimulateForces = false; List<ArgVert> aVL = aMD_IcosaSphere.icoPointCloud; for (int i = 0; i < aMD_IcosaSphere.icoPointCloud.Count - 1; i++) { sWrite.WriteLine(i.ToString() + " NodePath = " + aVL[i].itn.nodePath + "| N0 = " + aVL[i].avNeigbor[0].aV.itn.nodePath.ToString() + " d = " + aVL[i].avNeigbor[0].distFrom.ToString("F4") + " Sect = " + aVL[i].avNeigbor[0].aV.itn.sector.ToString() + " N1 = " + aVL[i].avNeigbor[1].aV.itn.nodePath.ToString() + " d = " + aVL[i].avNeigbor[1].distFrom.ToString("F4") + " Sect = " + aVL[i].avNeigbor[1].aV.itn.sector.ToString() + " N2 = " + aVL[i].avNeigbor[2].aV.itn.nodePath.ToString() + " d = " + aVL[i].avNeigbor[2].distFrom.ToString("F4") + " Sect = " + aVL[i].avNeigbor[2].aV.itn.sector.ToString() + " N3 = " + aVL[i].avNeigbor[3].aV.itn.nodePath.ToString() + " d = " + aVL[i].avNeigbor[3].distFrom.ToString("F4") + " Sect = " + aVL[i].avNeigbor[3].aV.itn.sector.ToString() + " N4 = " + aVL[i].avNeigbor[4].aV.itn.nodePath.ToString() + " d = " + aVL[i].avNeigbor[4].distFrom.ToString("F4") + " Sect = " + aVL[i].avNeigbor[4].aV.itn.sector.ToString() + " N5 = " + aVL[i].avNeigbor[5].aV.itn.nodePath.ToString() + " d = " + aVL[i].avNeigbor[5].distFrom.ToString("F4") + " Sect = " + aVL[i].avNeigbor[5].aV.itn.sector.ToString() + " v = " + aVL[i].vPos.ToString("F3") + " sector = " + aVL[i].itn.sector ); } }
in ArgosMeshDraft.cs
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 class NB { public ArgVert aV; public float distFrom; public NB() { aV = null; distFrom = float.MaxValue; } } public NB[] avNeigbor = new NB[6]; public ArgVert() { for(int i = 0; i<6; i++) { avNeigbor[i] = new NB(); avNeigbor[i].aV = this; } } public void insNeighbor(float dist, ArgVert aV_Contender)//Top 6 Contenders { NB avTmp; for (int i = 0; i<6; i++) { if(avNeigbor[i].distFrom > dist) { avTmp = avNeigbor[i]; for (int j = i; j<6; j++) { if (j == i) { avNeigbor[j].aV = aV_Contender; avNeigbor[j].distFrom = dist; } else { avNeigbor[j] = avTmp; } if(j<5) { avTmp = avNeigbor[j + 1]; } } } } } } 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) { 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; icoPointCloud.Add(aV); }
using UnityEngine; using System.Collections; using ProceduralToolkit; using UnityEngine.UI; using System.Collections.Generic; using System.IO; public class Cosahedra : MonoBehaviour { public Text NumTrisText; public float m_fRadius = 1.5f; public ArgosMeshDraft aMD = new ArgosMeshDraft(); public ArgosMeshDraft aMD_IcosaSphere = new ArgosMeshDraft(); MeshDraft mD_Tri = new MeshDraft(); public GameObject hexPreFab; public float m_fFact = 1; // force Multiplier StreamWriter sWrite; public int depth = 3; bool bSimulateForces = false; public enum ICO_Type { HEX, TRIANGLE, ICO_TREE_GENERATOR, }; public ICO_Type icoType; public class GO_Tracker { public GameObject go; public ArgVert aVNode; } public List<GO_Tracker> lstHex_GO = new List<GO_Tracker>(); void Start () { sWrite = new StreamWriter("Argos_ICO_Tree_Hex_Construction.txt"); aMD.Clear(); aMD.Add(MeshDraft.Icosahedron(m_fRadius)); aMD_IcosaSphere.Clear(); Create_GP(depth); Vector3 vApex = new Vector3(0.0f, 5.0f, 0.0f); //aMD_IcosaSphere.SetSortDist(vApex); //aMD_IcosaSphere.sortPointCloud(); Quaternion q; Vector3 vN_In; foreach(ArgVert aV in aMD_IcosaSphere.icoPointCloud) { vN_In = aV.vPos.normalized; q = Quaternion.LookRotation(vN_In); int lev0, lev1, lev2, lev3; GameObject gO; GO_Tracker gT; gO = (GameObject)Instantiate(hexPreFab, aV.vPos, q); gT = new GO_Tracker(); gT.go = gO; gT.aVNode = aV; lstHex_GO.Add(gT); lev3 = aV.itn.nodePath; lev0 = lev3 >> 6; lev1 = lev3 >> 4 & 3; lev2 = lev3 >> 2 & 3; lev3 = lev3 & 3; lstHex_GO[lstHex_GO.Count - 1].go.GetComponentInChildren<Text>().text = lev0.ToString() + lev1.ToString() + lev2.ToString() + lev3.ToString(); } foreach (GO_Tracker gActedUpon in lstHex_GO) { gActedUpon.go.transform.position = gActedUpon.aVNode.vPos; } //for (int i = 0; i < aMD_IcosaSphere.icoPointCloud.Count - 1; i++) //{ // //if (aMD_IcosaSphere.icoPointCloud[i].itn.sector == 5) // //{ // //sWrite.WriteLine("v = " + aMD_IcosaSphere.icoPointCloud[i].vPos.ToString("F3") + " sector = " + aMD_IcosaSphere.icoPointCloud[i].itn.sector // // + " NodePath = " + aMD_IcosaSphere.icoPointCloud[i].itn.nodePath + " sector = " + aMD_IcosaSphere.icoPointCloud[i].itn.sector // // + " dist = " + aMD_IcosaSphere.icoPointCloud[i].dist); // //} //} aMD_IcosaSphere.FlipNormals(); GetComponent<MeshFilter>().mesh = aMD_IcosaSphere.ToMesh(); } public void quickVoronoi() { Vector3 vForce; Vector3 vAccumForce; float dist_sqd; float fMag = 0; float delta = 0.05f; foreach (GO_Tracker gActedUpon in lstHex_GO) { vAccumForce = Vector3.zero; foreach (GO_Tracker gPushing in lstHex_GO) { if (gActedUpon != gPushing) { vForce = gActedUpon.aVNode.vPos - gPushing.aVNode.vPos; dist_sqd = vForce.x * vForce.x + vForce.y * vForce.y + vForce.z * vForce.z; vAccumForce += vForce.normalized / dist_sqd; } } fMag = vAccumForce.magnitude; vAccumForce = vAccumForce.normalized; gActedUpon.aVNode.vForce = 100f * vAccumForce; gActedUpon.aVNode.vPos += gActedUpon.aVNode.vForce * (delta * delta); gActedUpon.aVNode.vPos = gActedUpon.aVNode.vPos.normalized; gActedUpon.aVNode.vPos *= m_fRadius; } } public void OnStartButtonDown() { bSimulateForces = true; } public void OnStopButtonDown() { bSimulateForces = false; for (int i = 0; i < aMD_IcosaSphere.icoPointCloud.Count - 1; i++) { //if (aMD_IcosaSphere.icoPointCloud[i].itn.sector == 5) //{ sWrite.WriteLine(i.ToString() + " v = " + aMD_IcosaSphere.icoPointCloud[i].vPos.ToString("F3") + " sector = " + aMD_IcosaSphere.icoPointCloud[i].itn.sector + " NodePath = " + aMD_IcosaSphere.icoPointCloud[i].itn.nodePath + " sector = " + aMD_IcosaSphere.icoPointCloud[i].itn.sector + " dist = " + aMD_IcosaSphere.icoPointCloud[i].dist); //} } } void Update () { if (bSimulateForces) { quickVoronoi(); foreach (GO_Tracker gActedUpon in lstHex_GO) { gActedUpon.go.transform.position = gActedUpon.aVNode.vPos; } } } void OnApplicationQuit() { sWrite.Close(); } void Create_GP(int depth) { for(int i = 0; i<20; i++) { Vector3 v0 = aMD.vertices[aMD.triangles[i*3]]; Vector3 v1 = aMD.vertices[aMD.triangles[i*3 +1]]; Vector3 v2 = aMD.vertices[aMD.triangles[i*3 + 2]]; Color col = getWhite(); subdivide(v0, v1, v2, depth, col,i,0); } } void subdivide(Vector3 v1, Vector3 v2, Vector3 v3, int depth, Color col,int sector, int nID) { Vector3 v12, v23, v31; Vector3 v12_n, v23_n, v31_n; int i; if (depth == 0) { if (icoType == ICO_Type.HEX) { addHex(v1, v2, v3, col); } else if(icoType == ICO_Type.TRIANGLE) { addTriangle(v1, v2, v3, col); } else if(icoType == ICO_Type.ICO_TREE_GENERATOR) { addITG_Node(v1, v2, v3, sector, nID); } return; } v12 = (v1 + v2) / 2.0f; v23 = (v2 + v3) / 2.0f; v31 = (v3 + v1) / 2.0f; /* extrude midpoints to lie on unit sphere */ v12_n = v12.normalized * m_fRadius; v23_n = v23.normalized * m_fRadius; v31_n = v31.normalized * m_fRadius; int shifter = nID; shifter = shifter << 2; /* recursively subdivide new triangles */ subdivide(v1, v12_n, v31_n, depth - 1, col, sector, shifter | 0); subdivide(v12_n, v2, v23_n, depth - 1, col, sector, shifter | 1); subdivide(v31_n, v23_n, v3, depth - 1, col, sector, shifter | 2); subdivide(v23_n, v31_n, v12_n, depth - 1, col, sector, shifter | 3); } void addITG_Node(Vector3 v0, Vector3 v1, Vector3 v2,int Sector, int nID) { mD_Tri = MeshDraft.Triangle(v0, v1, v2); aMD_IcosaSphere.Add_ITN_Node(mD_Tri, Sector, nID); } void addTriangle(Vector3 v0, Vector3 v1, Vector3 v2, Color col) { mD_Tri.Clear(); mD_Tri = MeshDraft.Triangle(v0, v1, v2); mD_Tri.Paint(col); aMD_IcosaSphere.AddTriQual(mD_Tri); } void addHex(Vector3 v0, Vector3 v1, Vector3 v2, Color col) { mD_Tri.Clear(); mD_Tri = MeshDraft.Triangle(v0, v1, v2); mD_Tri.Paint(col); aMD_IcosaSphere.AddHex(mD_Tri); } public void writeMesh() { GetComponent<MeshFilter>().mesh = aMD_IcosaSphere.ToMesh(); } public ArgosMeshDraft getArgosMeshDraft() { return aMD_IcosaSphere; } Color getIDXolor(int i) { Color col; col.r = 0.2f + (float)(i) * 0.8f / 20f ; col.g = 0.5f + (float)(i) * 0.5f / 20f; col.b = 1f - (float)(i) * 0.8f / 20f; col.a = 1f; return col; } Color getWhite() // :) { Color col; col.r = 1f; col.g = 1f; col.b = 1f; col.a = 1f; return col; } Color getINColor(int i) { Color col; col.r = (float)(i) / 1024f; col.g = 1f - (float)(i) / 1024f; col.b = 0.5f - (float)(i) / 1024f; if(col.b>0) col.b = 1f- (float)(i) / 1024f; col.a = 1f; return col; } }