
Unity Native Spline
SPHERE EXPANDER – FROM Fundamental Flower
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using ProceduralToolkit;
using UnityEngine.UI;
using System;
using ArgosTweenSpacePuppy;
using VRTK;
using System.IO;
using UnityEngine.EventSystems;
using System.Linq;
public class Sphere_Expander : MonoBehaviour
{
public bool bSeparate_Faces = false;
public bool bDrawTetrahedron = false;
public int totalVerts = 0;
public int filteredVerts = 0;
public int vSort_Count_0;
public int vSort_Count_1;
public int vSort_Count_2;
private ArgosMeshDraft aMD_TetraTerrean;
private ArgosMeshDraft aMD_TT_Sleeve;
private ArgosMeshDraft[] aMD_tt_Faces = new ArgosMeshDraft[4];
private GameObject[] tt_Faces = new GameObject[4];
private ArgosMeshDraft aMD_Spheres;
private ArgosMeshDraft cylinder_MD;
private ArgosMeshDraft scythe_MD;
private GameObject scythe_GO;
public Color col_edge_Cylinder;
public Color col_Sphere;
private GameObject[] spheres = new GameObject[4];
private Vector3[] sphere_pos = new Vector3[4];
public GameObject meshPF;
public GameObject tetra_Vert_GOPF;
private GameObject[] tetra_Verts_GO = new GameObject[4];
private GameObject[] tetra_Edges = new GameObject[6];
private GameObject TetraTerrien_GO;
private GameObject TT_Sleeve_GO;
public float[] lengths = new float[256];
public float[] hyperbola_of_R = new float[256];
public int all_Shape_Depth = 4;
Vector3[] vC = new Vector3[4];
public class Vector_Sort
{
public Vector3 vert;
public float dist = 0;
public int vIDX = 0;
}
internal class PlaneHelper
{
/// <summary>
/// Returns a value indicating what side (positive/negative) of a plane a point is
/// </summary>
/// <param name="point">The point to check with</param>
/// <param name="plane">The plane to check against</param>
/// <returns>Greater than zero if on the positive side, less than zero if on the negative size, 0 otherwise</returns>
public static float ClassifyPoint(ref Vector3 point, ref Plane plane)
{
return point.x * plane.Normal.x + point.y * plane.Normal.y + point.z * plane.Normal.z + plane.D;
}
/// <summary>
/// Returns the perpendicular distance from a point to a plane
/// </summary>
/// <param name="point">The point to check</param>
/// <param name="plane">The place to check</param>
/// <returns>The perpendicular distance from the point to the plane</returns>
public static float PerpendicularDistance(ref Vector3 point, ref Plane plane)
{
// dist = (ax + by + cz + d) / sqrt(a*a + b*b + c*c)
return Mathf.Abs((plane.Normal.x * point.x + plane.Normal.y * point.y + plane.Normal.z * point.z)
/ Mathf.Sqrt(plane.Normal.x * plane.Normal.x + plane.Normal.y * plane.Normal.y + plane.Normal.z * plane.Normal.z));
}
}
public struct Plane
{
#region Public Fields
public float D;
public Vector3 Normal;
#endregion Public Fields
#region Constructors
public Plane(Vector4 value)
: this(new Vector3(value.x, value.y, value.z), value.w)
{
}
public Plane(Vector3 normal, float d)
{
Normal = normal;
D = d;
}
public Plane(Vector3 a, Vector3 b, Vector3 c)
{
Vector3 ab = b - a;
Vector3 ac = c - a;
Vector3 cross = Vector3.Cross(ab, ac);
Normal = Vector3.Normalize(cross);
D = -(Vector3.Dot(Normal, a));
}
public Plane(float a, float b, float c, float d)
: this(new Vector3(a, b, c), d)
{
}
#endregion Constructors
public override string ToString()
{
return string.Format("{{Normal:{0} D:{1}}}", Normal, D);
}
}
public enum TT_TYPE
{
SPHERICAL,
HYPERBOLIC,
OTHER,
NONE,
}
public TT_TYPE ttType = TT_TYPE.SPHERICAL;
public bool bSpheresON = true;
public bool bTetraTerrean_On = false;
[Range(0, 50f)]
public float tetra_Radius;
private float tetra_Radius_Last = 0;
[Range(0, 100f)]
public float scale_TT= 100f;
[Range(0, 500f)]
public float sphere_Radius;
private float sphere_Radius_Last = 0;
[Range(0, 0.5f)]
public float cylinder_Radius;
private Vector3[] tetra_Verts = new Vector3[4];
private Vector3[] face_Centers = new Vector3[4];
[Space(12)]
[Header("Hyperbolic Settings")]
[Space(12)]
[Range(0, 1f)]
public float base_Distance;
[Range(0, 1f)]
public float tangent_Base;
[Range(0, 1f)]
public float tangent_H;
[Range(0, 1f)]
public float smidge;
public GameObject H_Editor_Label;
public GameObject C_Editor_Label;
public GameObject B_Editor_Label;
public GameObject I_Editor_Label;
public GameObject T1_Editor_Label;
public GameObject T2_Editor_Label;
private int frameCount = 1;
private Vector3 vCHn, vIHn, vT1n, vT2n;
private Vector3 vIH;
StreamWriter sWrite;
public bool bPrint_Trace = false;
private Vector3[] beeS = new Vector3[4];
StreamWriter sLineVectors;
private ArgosMeshDraft aMD_Nurbs_Mesh;
GameObject pQuad_CARBON_LINE_go;
private ArgosMeshDraft aMD_PQUAD_TMP;
public enum RESOLUTION
{
RES_LOW,
RES_MED,
RES_HIGH,
}
public RESOLUTION rESOLUTION = RESOLUTION.RES_LOW;
private RESOLUTION resolution_Last = RESOLUTION.RES_LOW;
private int nRESOLUTION = 7;
private List<Vector3> lst_mesh_v = new List<Vector3>();
public float[] spline_lengths = new float[256];
[Range(0, 10f)]
public float short_Tan_mag = 1;
[Range(0, 10f)]
public float long_Tan_mag = 1;
void Start()
{
sLineVectors = new StreamWriter("sLineVectors.txt");
aMD_TetraTerrean = new ArgosMeshDraft();
aMD_Spheres = new ArgosMeshDraft();
aMD_Spheres.Add(MeshDraft.Sphere(1,16,16));
cylinder_MD = new ArgosMeshDraft();
aMD_TT_Sleeve = new ArgosMeshDraft();
scythe_MD = new ArgosMeshDraft();
scythe_GO = Instantiate(meshPF, transform);
scythe_GO.name = "SCYTHE_OUTLINE";
aMD_Nurbs_Mesh = new ArgosMeshDraft();
pQuad_CARBON_LINE_go = Instantiate(meshPF, transform);
pQuad_CARBON_LINE_go.name = "pQuad_CARBON_LINE_go";
pQuad_CARBON_LINE_go.GetComponent<MeshRenderer>().enabled = false;//so we can see the TT
sWrite = new StreamWriter("Hyperbolic_Params.txt");
for (int i = 0; i<4; i++)
{
spheres[i] = Instantiate(meshPF, transform);
spheres[i].name = "sphere_" + i.ToString();
SetColor_Element(col_Sphere, spheres[i]);
spheres[i].GetComponent<MeshFilter>().mesh = aMD_Spheres.ToMeshInternal();
tetra_Verts_GO[i] = Instantiate(tetra_Vert_GOPF, transform);
tetra_Verts_GO[i].name = "TetVERT_" + i.ToString();
tt_Faces[i] = Instantiate(meshPF, transform);
tt_Faces[i].name = "TT_Face_" + i.ToString();
aMD_tt_Faces[i] = new ArgosMeshDraft();
}
for(int i = 0; i<6; i++)
{
tetra_Edges[i] = Instantiate(meshPF, transform);
tetra_Edges[i].name = "edge_" + i.ToString();
SetColor_Element(col_edge_Cylinder, tetra_Edges[i]);
tetra_Edges[i].GetComponent<MeshFilter>().mesh = cylinder_MD.ToMeshInternal();
}
Set_Tetra_Verts(tetra_Radius);
TetraTerrien_GO = Instantiate(meshPF, transform);
TetraTerrien_GO.name = "TetraTerrien_GO";
aMD_TetraTerrean.Clear();
//Create_TETRA_TERREAN(all_Shape_Depth);
//TetraTerrien_GO.GetComponent<MeshFilter>().mesh = aMD_TetraTerrean.ToMeshInternal();
TT_Sleeve_GO = Instantiate(meshPF, transform);
TT_Sleeve_GO.name = "TT_Sleeve_GO";
aMD_TT_Sleeve.Clear();
aMD_PQUAD_TMP = new ArgosMeshDraft();
}
/// <image url="$(SolutionDir)\EMB\Quad_Nurb.png" scale="0.15" />
public void PQuad_SetUp_VertsAndTans()
{
Vector3 v0;
Vector3 v1;
Vector3 v2;
Vector3 v3;
Vector3 t01;
Vector3 t10;
Vector3 t13;
Vector3 t31;
Vector3 t23;
Vector3 t32;
Vector3 t20;
Vector3 t02;
v0 = tetra_Verts[2];
v1 = v0;
v1.y = -v1.y;
v2 = tetra_Verts[3];
v3 = v2;
v3.y = -v3.y;
//short_Tan_mag;
//long_Tan_mag;
Vector3[] vTansNorm = new Vector3[4];
vTansNorm[0] = -v0.normalized;
vTansNorm[1] = -v1.normalized;
vTansNorm[2] = -v2.normalized;
vTansNorm[3] = -v3.normalized;
t01 = v0 + vTansNorm[0] * short_Tan_mag;
t02 = v0 + vTansNorm[0] * long_Tan_mag;
t10 = v1 + vTansNorm[1] * short_Tan_mag;
t13 = v1 + vTansNorm[1] * long_Tan_mag;
t23 = v2 + vTansNorm[2] * short_Tan_mag;
t20 = v2 + vTansNorm[2] * long_Tan_mag;
t32 = v3 + vTansNorm[3] * short_Tan_mag;
t31 = v3 + vTansNorm[3] * long_Tan_mag;
P_Quad_Generate(v0, v1, v2, v3,
t01, t10, t13, t31,
t23, t32, t20, t02);
}
public void P_Quad_Generate(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3,
Vector3 t01, Vector3 t10, Vector3 t13, Vector3 t31,
Vector3 t23, Vector3 t32, Vector3 t20, Vector3 t02)
{
Set_Resolution();
lst_mesh_v.Clear();
aMD_Nurbs_Mesh.Clear();
float u = 0;
float v = 0;
float du = 1 / (float)nRESOLUTION;
float dv = 1 / (float)nRESOLUTION;
Vector3 t0, t1;
Vector3 p0, p1;
Vector3 p;
for (int i = 0; i < nRESOLUTION + 1; i++)
{
t0 = GetPointOnBezierCurve(t02, t01, t10, t13, get_Adjusted(u, ref spline_lengths));
p0 = GetPointOnBezierCurve(v0, t01, t10, v1, get_Adjusted(u, ref spline_lengths));
t1 = GetPointOnBezierCurve(t20, t23, t32, t31, get_Adjusted(u, ref spline_lengths));
p1 = GetPointOnBezierCurve(v2, t23, t32, v3, get_Adjusted(u, ref spline_lengths));
Compute_Dist(ref spline_lengths, v0, t02, t20, v2);
v = 0f;
for (int j = 0; j < nRESOLUTION + 1; j++)
{
p = GetPointOnBezierCurve(p0, t0, t1, p1, get_Adjusted(v, ref spline_lengths));
lst_mesh_v.Add(p);
v += dv;
}
u += du;
}
int stride = nRESOLUTION + 1;
int k = 0;
for (int i = 0; i < nRESOLUTION; i++)
{
for (int j = 0; j < nRESOLUTION; j++)
{
aMD_Nurbs_Mesh.Add(MeshDraft.Quad(lst_mesh_v[k], lst_mesh_v[k + 1], lst_mesh_v[k + stride + 1], lst_mesh_v[k + stride]));
k++;
}
k++;
}
Quaternion q;
float angle = 120;
ArgosMeshDraft amdTmp = new ArgosMeshDraft();
amdTmp.Copy_MeshDraft(aMD_Nurbs_Mesh);
amdTmp.Rotate(Quaternion.AngleAxis(angle, Vector3.up));
aMD_Nurbs_Mesh.Add(amdTmp);
amdTmp.Rotate(Quaternion.AngleAxis(angle, Vector3.up));
aMD_Nurbs_Mesh.Add(amdTmp);
aMD_PQUAD_TMP.Clear();
subdivide_PQUAD_TRIANGLE(tetra_Verts[2], tetra_Verts[3], tetra_Verts[1], all_Shape_Depth, spheres[2].transform.localPosition, 3, true);
aMD_Nurbs_Mesh.Add(aMD_PQUAD_TMP);
aMD_PQUAD_TMP.Rotate(Quaternion.AngleAxis(180, Vector3.forward));
aMD_Nurbs_Mesh.Add(aMD_PQUAD_TMP);
pQuad_CARBON_LINE_go.GetComponent<MeshFilter>().mesh = aMD_Nurbs_Mesh.ToMeshInternal();
pQuad_CARBON_LINE_go.GetComponent<MeshFilter>().mesh.RecalculateNormals(60);
}
void subdivide_PQUAD_TRIANGLE(Vector3 v1, Vector3 v2, Vector3 v3, int depth, Vector3 sector_Foc, int nID, bool bFlipNorm)
{
Vector3 v12, v23, v31;
Vector3 v12_n, v23_n, v31_n;
if (depth == 0)
{
if (bFlipNorm)
{
addTriangle_UV_Tag_PQUAD(v1, v3, v2, (float)nID);
}
else
{
//if (nID == 1)
//{
// vTest[i] = v1;
// vTest2[i] = v2;
// i++;
//}
addTriangle_UV_Tag_PQUAD(v3, v2, v1, (float)nID);
}
return;
}
v12 = (v1 + v2) / 2.0f;
v23 = (v2 + v3) / 2.0f;
v31 = (v3 + v1) / 2.0f;
v12_n = Sphere_Surf(v12, sector_Foc); //sector_Foc
v23_n = Sphere_Surf(v23, sector_Foc);
v31_n = Sphere_Surf(v31, sector_Foc);
//v12_n = v12; //sector_Foc
//v23_n = v23;
//v31_n = v31;
/* recursively subdivide new triangles */
subdivide_PQUAD_TRIANGLE(v1, v12_n, v31_n, depth - 1, sector_Foc, 1, bFlipNorm);
subdivide_PQUAD_TRIANGLE(v12_n, v2, v23_n, depth - 1, sector_Foc, 2, bFlipNorm);
subdivide_PQUAD_TRIANGLE(v31_n, v23_n, v3, depth - 1, sector_Foc, 3, bFlipNorm);
subdivide_PQUAD_TRIANGLE(v23_n, v31_n, v12_n, depth - 1, sector_Foc, 4, bFlipNorm);
}
private void Create_Top_Bottom(int depth)
{
//sleeve(tetra_Verts[1], tetra_Verts[2], tetra_Verts[3], spheres[2].transform.localPosition);
subdivide_CarbonLine(tetra_Verts[1], tetra_Verts[3], tetra_Verts[2], depth, spheres[2].transform.localPosition, 3, false);
List<Vector_Sort>[] vsortList = new List<Vector_Sort>[3];
vsortList[0] = new List<Vector_Sort>();
vsortList[1] = new List<Vector_Sort>();
vsortList[2] = new List<Vector_Sort>();
int[] id = new int[] { 0, 1, 2, 0, 2, 3, 0, 3, 1 };
Vector3 vert;
for (int j = 0; j < 3; j++)
{
Plane p = new Plane(tetra_Verts[id[3 * j]], tetra_Verts[id[3 * j + 1]], tetra_Verts[id[3 * j + 2]]);
p.D = p.D * 0.999f;
Vector_Sort vs;
filteredVerts = 0;
for (int i = 0; i < aMD_TT_Sleeve.vertices.Count; i++)
{
vert = aMD_TT_Sleeve.vertices[i];
float res = PlaneHelper.ClassifyPoint(ref vert, ref p);
if (res > 0)
{
filteredVerts++;
vs = new Vector_Sort();
vs.vert = vert;
vs.vIDX = i;
vsortList[j].Add(vs);
}
}
RemoveDuplicates(vsortList[j]);
for (int i = 0; i < vsortList[j].Count; i++)
{
vsortList[j][i].dist = (tetra_Verts[j + 1] - vsortList[j][i].vert).magnitude;
}
var ordered = from element in vsortList[j]
orderby element.dist
select element;
vsortList[j] = ordered.ToList<Vector_Sort>();
}
for (int i = 0; i < aMD_TT_Sleeve.vertices.Count; i++)
{
aMD_TT_Sleeve.vertices[i] = Sphere_Surf(aMD_TT_Sleeve.vertices[i], spheres[2].transform.localPosition);
}
Plane p2 = new Plane(Vector3.up, 0);
int vertCount = aMD_TT_Sleeve.vertices.Count;
ArgosMeshDraft amdTemp = new ArgosMeshDraft();
amdTemp.Add(aMD_TT_Sleeve);
aMD_TT_Sleeve.FlipTriangles();
aMD_TT_Sleeve.Add(amdTemp);
aMD_TT_Sleeve.FlipNormals();
float d;
for (int i = 0; i < vertCount; i++)//FLIP
{
vert = aMD_TT_Sleeve.vertices[i];
d = PlaneHelper.ClassifyPoint(ref vert, ref p2);
aMD_TT_Sleeve.vertices[i] = vert - 2f * d * Vector3.up;
}
List<Vector3> vInnerLower = new List<Vector3>();
List<Vector3> vInnerUpper = new List<Vector3>();
List<Vector3> vPrint = new List<Vector3>();
for (int j = 0; j < 3; j++)
{
for (int i = 0; i < vsortList[j].Count; i++)
{
vert = aMD_TT_Sleeve.vertices[vsortList[j][i].vIDX];
//vCurr.y = 0;
d = PlaneHelper.ClassifyPoint(ref vert, ref p2);
if (j == 0)
{
vPrint.Add(vert - 2f * d * Vector3.up);
}
vInnerLower.Add(vert);
vInnerUpper.Add(vert - 2f * d * Vector3.up);
}
}
aMD_TT_Sleeve.Add(MeshDraft.Band(vInnerUpper, vInnerLower));
aMD_TT_Sleeve.Add(MeshDraft.Band(vInnerLower, vInnerUpper));
Generate_Line_List(vPrint);
vSort_Count_0 = vsortList[0].Count;
vSort_Count_1 = vsortList[1].Count;
vSort_Count_2 = vsortList[2].Count;
}
private float get_Adjusted(float t, ref float[] lengths)
{
int i = 0;
while (i < 256 && lengths[i] < t)
{
i++;
}
return (float)i / 256;
}
private void Compute_Dist(ref float[] lengths, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)
{
float t = 0.0f;
float dt = 1f / 256;
Vector3 vB = GetPointOnBezierCurve(p0, p1, p2, p3, t);
Vector3 vB_Last = vB;
float running_Len = 0;
for (int i = 0; i < 256; i++)
{
vB = GetPointOnBezierCurve(p0, p1, p2, p3, t);
running_Len += (vB - vB_Last).magnitude;
lengths[i] = running_Len;
vB_Last = vB;
t += dt;
}
for (int i = 0; i < 256; i++)
{
lengths[i] /= running_Len;
}
}
private void Set_Resolution()
{
if (rESOLUTION != resolution_Last)
{
if (rESOLUTION == RESOLUTION.RES_LOW)
{
nRESOLUTION = 7;
}
else if (rESOLUTION == RESOLUTION.RES_MED)
{
nRESOLUTION = 18;
}
else if (rESOLUTION == RESOLUTION.RES_HIGH)
{
nRESOLUTION = 36;
}
}
resolution_Last = rESOLUTION;
}
//void OnDrawGizmos()
//{
// Gizmos.DrawIcon(H_Editor_Label.transform.position, "H.png", true);
// Gizmos.DrawIcon(C_Editor_Label.transform.position, "C.png", true);
// Gizmos.DrawIcon(I_Editor_Label.transform.position, "I.png", true);
// Gizmos.DrawIcon(B_Editor_Label.transform.position, "B.png", true);
// Gizmos.DrawIcon(T1_Editor_Label.transform.position, "T1.png", true);
// Gizmos.DrawIcon(T2_Editor_Label.transform.position, "T2.png", true);
// Gizmos.color = Color.green;
// Gizmos.DrawLine(B_Editor_Label.transform.position, T1_Editor_Label.transform.position);
// Gizmos.DrawLine(H_Editor_Label.transform.position, T2_Editor_Label.transform.position);
//}
private void OnApplicationQuit()
{
sWrite.Close();
}
/// <image url="$(SolutionDir)\EMB\hyperbole2.png" scale="0.35"></image>
private void build_Reference_Hyperbolic_Spline(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 vI)
{
//p4 = H
float t = 0.0f;
float dt = 1f / 256;
Vector3 vB = GetPointOnBezierCurve(p0, p1, p2, p3, t);
Vector3 vB_Last = vB;
float running_Len = 0;
float vI_Len = vI.magnitude;
Vector3 vIn = vI.normalized;
for (int i = 0; i < 256; i++)
{
vB = GetPointOnBezierCurve(p0, p1, p2, p3, t);
running_Len += (vB - vB_Last).magnitude;
lengths[i] = running_Len;
hyperbola_of_R[i] = Vector3.Dot(vB, vIn);
vB_Last = vB;
t += dt;
}
for (int i = 0; i < 256; i++)
{
lengths[i] /= running_Len;
}
}
public void Print_Trace(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 vI)
{
for (int i = 0; i < 256; i++)
{
sWrite.WriteLine(i.ToString() + "\t " + " -\t " + hyperbola_of_R[i].ToString("F2"));
}
sWrite.WriteLine("p0 Base " + "\t " + " -\t " + p0.ToString("F2"));
sWrite.WriteLine("p1 Tangent_0 " + "\t " + " -\t " + p1.ToString("F2"));
sWrite.WriteLine("p2 Tangent_1 " + "\t " + " -\t " + p2.ToString("F2"));
sWrite.WriteLine("p3 H " + "\t " + " -\t " + p3.ToString("F2"));
sWrite.WriteLine("vI " + "\t " + " -\t " + vI.ToString("F2"));
}
private void SetColor_Element(Color col, GameObject go)
{
float alpha = col.a;
float alpha_out = alpha / 3f;
Color cola = col;
cola.a = alpha_out;
go.GetComponent<MeshRenderer>().material.SetColor("_EmissionColor", cola);
go.GetComponent<MeshRenderer>().material.SetColor("_Color", col);
}
public void Set_Tetra_Verts(float radius)
{
float tetrahedralAngle = Mathf.PI * -19.471220333f / 180;
float segmentAngle = Mathf.PI * 2 / 3;
float currentAngle = 0f;
Vector3 v = new Vector3(0, radius, 0);
tetra_Verts[0] = v;
for (var i = 1; i < 4; i++)
{
tetra_Verts[i] = PTUtils.PointOnSphere(radius, currentAngle, tetrahedralAngle);
currentAngle += segmentAngle;
}
face_Centers[0] = (tetra_Verts[0] + tetra_Verts[1] + tetra_Verts[2]) / 3f;
face_Centers[1] = (tetra_Verts[0] + tetra_Verts[2] + tetra_Verts[3]) / 3f;
face_Centers[2] = (tetra_Verts[1] + tetra_Verts[2] + tetra_Verts[3]) / 3f;
face_Centers[3] = (tetra_Verts[0] + tetra_Verts[1] + tetra_Verts[3]) / 3f;
float edge_length = (tetra_Verts[0] - tetra_Verts[1]).magnitude;
edge_length = radius * 2f * Mathf.Sqrt(2f) / Mathf.Sqrt(3);
cylinder_MD.Add(MeshDraft.Cylinder_Z(cylinder_Radius, 5, edge_length));
//tetra_Edges[0].transform.localPosition = tetra_Verts[0];
//tetra_Edges[0].transform.localRotation = Quaternion.LookRotation(tetra_Verts[1] - tetra_Verts[0]);
//tetra_Edges[0].GetComponent<MeshFilter>().mesh = cylinder_MD.ToMeshInternal();
//tetra_Edges[1].transform.localPosition = tetra_Verts[1];
//tetra_Edges[1].transform.localRotation = Quaternion.LookRotation(tetra_Verts[2] - tetra_Verts[1]);
//tetra_Edges[1].GetComponent<MeshFilter>().mesh = cylinder_MD.ToMeshInternal();
//tetra_Edges[2].transform.localPosition = tetra_Verts[2];
//tetra_Edges[2].transform.localRotation = Quaternion.LookRotation(tetra_Verts[3] - tetra_Verts[2]);
//tetra_Edges[2].GetComponent<MeshFilter>().mesh = cylinder_MD.ToMeshInternal();
//tetra_Edges[3].transform.localPosition = tetra_Verts[3];
//tetra_Edges[3].transform.localRotation = Quaternion.LookRotation(tetra_Verts[0] - tetra_Verts[3]);
//tetra_Edges[3].GetComponent<MeshFilter>().mesh = cylinder_MD.ToMeshInternal();
//tetra_Edges[4].transform.localPosition = tetra_Verts[1];
//tetra_Edges[4].transform.localRotation = Quaternion.LookRotation(tetra_Verts[3] - tetra_Verts[1]);
//tetra_Edges[4].GetComponent<MeshFilter>().mesh = cylinder_MD.ToMeshInternal();
//tetra_Edges[5].transform.localPosition = tetra_Verts[2];
//tetra_Edges[5].transform.localRotation = Quaternion.LookRotation(tetra_Verts[0] - tetra_Verts[2]);
//tetra_Edges[5].GetComponent<MeshFilter>().mesh = cylinder_MD.ToMeshInternal();
}
private void Create_Scythe(int depth)
{
subdivide_CarbonLine(tetra_Verts[1], tetra_Verts[3], tetra_Verts[2], depth, spheres[2].transform.localPosition, 3, false);
}
void Update()
{
PQuad_SetUp_VertsAndTans();
cylinder_MD.Clear();
scythe_MD.Clear();
Set_Tetra_Verts(tetra_Radius);
if (sphere_Radius_Last != sphere_Radius)
{
float face_dist;
float tetra_Height;
Vector3 face_Norm;
float a, b;
aMD_Spheres.Clear();
aMD_Spheres.Add(MeshDraft.Sphere(sphere_Radius, 36, 32));
for (int i = 0; i < 4; i++)
{
face_dist = face_Centers[i].magnitude;
tetra_Height = 1.33333f * tetra_Radius;
a = 2 * Mathf.Sqrt(2) / 3;
b = Mathf.Sqrt(sphere_Radius * sphere_Radius - tetra_Radius * tetra_Radius * 8f / 9f);
face_Norm = face_Centers[i].normalized;
spheres[i].transform.localPosition = face_Norm * (tetra_Radius / 3 + b);
spheres[i].transform.localRotation = Quaternion.LookRotation(sphere_pos[i]);
spheres[i].GetComponent<MeshFilter>().mesh = aMD_Spheres.ToMeshInternal();
tetra_Verts_GO[i].transform.localPosition = tetra_Verts[i];
}
}
sphere_Radius_Last = sphere_Radius;
tetra_Radius_Last = tetra_Radius;
if (bSpheresON)
{
ShowSpheres(true);
}
else
{
ShowSpheres(false);
}
aMD_TetraTerrean.Clear();
for (int i = 0; i < 4; i++)
{
aMD_tt_Faces[i].Clear();
}
Create_TETRA_TERREAN(all_Shape_Depth);
if (bSeparate_Faces)
{
for (int i = 0; i < 4; i++)
{
tt_Faces[i].GetComponent<MeshFilter>().mesh = aMD_tt_Faces[i].ToMeshInternal();
}
}
else
{
aMD_TetraTerrean.FlipTriangles();
aMD_TetraTerrean.FlipNormals();
TetraTerrien_GO.GetComponent<MeshFilter>().mesh = aMD_TetraTerrean.ToMeshInternal();
TetraTerrien_GO.GetComponent<MeshFilter>().mesh.RecalculateNormals(60);
}
//Create_Scythe(all_Shape_Depth);
//aMD_TT_Sleeve.Clear();
//Create_TETRA_TERREAN_Sleeve(all_Shape_Depth);
//TT_Sleeve_GO.GetComponent<MeshFilter>().mesh = aMD_TT_Sleeve.ToMeshInternal();
//TT_Sleeve_GO.GetComponent<MeshFilter>().mesh.RecalculateNormals(60);
sphere_Radius_Last = sphere_Radius;
tetra_Radius_Last = tetra_Radius;
}
private void ShowSpheres(bool bOn)
{
for(int i = 0; i<4; i++)
{
spheres[i].GetComponent<MeshRenderer>().enabled = bOn;
}
}
public void Calc_Tetra_Verts(float radius)
{
float tetrahedralAngle = Mathf.PI * -19.471220333f / 180;
float segmentAngle = Mathf.PI * 2 / 3;
float currentAngle = 0f;
Vector3 v = new Vector3(0, radius, 0);
sphere_pos[0] = v;
for (var i = 1; i < 4; i++)
{
sphere_pos[i] = PTUtils.PointOnSphere(radius, currentAngle, tetrahedralAngle);
currentAngle += segmentAngle;
}
}
private Vector3 Sphere_Surf(Vector3 vP0, Vector3 sector_Focus)
{
Vector3 l = vP0.normalized;
Vector3 OminC = -sector_Focus;
float rsqr = sphere_Radius * sphere_Radius;
float dotLOminC = Vector3.Dot(l, OminC);
float Omag = OminC.magnitude;
float d = -dotLOminC - Mathf.Sqrt(dotLOminC * dotLOminC - Omag * Omag + sphere_Radius * sphere_Radius);
return l * d;
}
private Vector3 Hyperbolic(Vector3 vP0, Vector3 face_Center)
{
Vector3 vFCn = face_Center.normalized;
Vector3 dotV = Vector3.Dot(vP0, vFCn)* vFCn;
Vector3 radV = vP0 - dotV;
Vector3 vP0n = vP0.normalized;
float radial_mag = radV.magnitude;
float perc = (radial_mag / vIH.magnitude)*255;
float gVal = 0f;
//if (perc < 256)
//{
gVal = hyperbola_of_R[(int)perc];
//}
return (gVal*vFCn + radV);
}
void Extrude_1(Vector3 v1, Vector3 v2, Vector3 v3, int nID, Vector3 sector_Foc)
{
Vector3 nSect = tetra_Verts[0].normalized;
float spar = (1f / 9f) * sphere_Radius;
float d1, d2, d3;
d1 = Vector3.Dot(v1, nSect);
d2 = Vector3.Dot(v2, nSect);
d3 = Vector3.Dot(v3, nSect);
Vector3 ob1 = (spar - d1) * nSect;
Vector3 ob2 = (spar - d2) * nSect;
Vector3 ob3 = (spar - d3) * nSect;
if (nID == 0)
{
addTriangle(v1 + 2 * ob1, v2 + 2 * ob2, v3 + 2 * ob3);
}
else
{
ob1 = PosCheck(nSect, d1, (d1 / spar), v1 - d1 * nSect);
ob2 = PosCheck(nSect, d2, (d2 / spar), v2 - d2 * nSect);
ob3 = PosCheck(nSect, d3, (d3 / spar), v3 - d3 * nSect);
addTriangle(v1 + ob1, v2 + ob2, v3 + ob3);
}
}
private Vector3 PosCheck(Vector3 v1, float d, float multiplier, Vector3 vHorz)
{
return Vector3.zero;
}
public static void RemoveDuplicates(List<Vector_Sort> list)
{
if (list == null)
{
return;
}
int i = 1;
while (i < list.Count)
{
int j = 0;
bool remove = false;
while (j < i && !remove)
{
if (list[i].vert.Equals(list[j].vert))
{
remove = true;
}
j++;
}
if (remove)
{
list.RemoveAt(i);
}
else
{
i++;
}
}
}
private void Create_TETRA_TERREAN_Sleeve(int depth)
{
//sleeve(tetra_Verts[1], tetra_Verts[2], tetra_Verts[3], spheres[2].transform.localPosition);
subdivide_CarbonLine(tetra_Verts[1], tetra_Verts[3], tetra_Verts[2], depth, spheres[2].transform.localPosition, 3, false);
List<Vector_Sort>[] vsortList = new List<Vector_Sort>[3];
vsortList[0] = new List<Vector_Sort>();
vsortList[1] = new List<Vector_Sort>();
vsortList[2] = new List<Vector_Sort>();
int[] id = new int [] { 0, 1, 2, 0, 2, 3, 0, 3, 1 };
Vector3 vert;
for (int j = 0; j < 3; j++)
{
Plane p = new Plane(tetra_Verts[id[3*j]], tetra_Verts[id[3*j+1]], tetra_Verts[id[3*j+2]]);
p.D = p.D * 0.999f;
Vector_Sort vs;
filteredVerts = 0;
for (int i = 0; i < aMD_TT_Sleeve.vertices.Count; i++)
{
vert = aMD_TT_Sleeve.vertices[i];
float res = PlaneHelper.ClassifyPoint(ref vert, ref p);
if (res > 0)
{
filteredVerts++;
vs = new Vector_Sort();
vs.vert = vert;
vs.vIDX = i;
vsortList[j].Add(vs);
}
}
RemoveDuplicates(vsortList[j]);
for (int i = 0; i < vsortList[j].Count; i++)
{
vsortList[j][i].dist = (tetra_Verts[j+1] - vsortList[j][i].vert).magnitude;
}
var ordered = from element in vsortList[j]
orderby element.dist
select element;
vsortList[j] = ordered.ToList<Vector_Sort>();
}
for(int i = 0; i < aMD_TT_Sleeve.vertices.Count; i++)
{
aMD_TT_Sleeve.vertices[i] = Sphere_Surf(aMD_TT_Sleeve.vertices[i], spheres[2].transform.localPosition);
}
Plane p2 = new Plane(Vector3.up, 0);
int vertCount = aMD_TT_Sleeve.vertices.Count;
ArgosMeshDraft amdTemp = new ArgosMeshDraft();
amdTemp.Add(aMD_TT_Sleeve);
aMD_TT_Sleeve.FlipTriangles();
aMD_TT_Sleeve.Add(amdTemp);
aMD_TT_Sleeve.FlipNormals();
float d;
for(int i = 0; i < vertCount; i++)//FLIP
{
vert = aMD_TT_Sleeve.vertices[i];
d = PlaneHelper.ClassifyPoint(ref vert, ref p2);
aMD_TT_Sleeve.vertices[i] = vert - 2f * d * Vector3.up;
}
List<Vector3> vInnerLower = new List<Vector3>();
List<Vector3> vInnerUpper = new List<Vector3>();
List<Vector3> vPrint = new List<Vector3>();
for (int j = 0; j < 3; j++)
{
for (int i = 0; i < vsortList[j].Count; i++)
{
vert = aMD_TT_Sleeve.vertices[vsortList[j][i].vIDX];
//vCurr.y = 0;
d = PlaneHelper.ClassifyPoint(ref vert, ref p2);
if(j==0)
{
vPrint.Add(vert - 2f * d * Vector3.up);
}
vInnerLower.Add(vert);
vInnerUpper.Add(vert - 2f * d * Vector3.up);
}
}
aMD_TT_Sleeve.Add(MeshDraft.Band(vInnerUpper, vInnerLower));
aMD_TT_Sleeve.Add(MeshDraft.Band(vInnerLower, vInnerUpper));
Generate_Line_List(vPrint);
vSort_Count_0 = vsortList[0].Count;
vSort_Count_1 = vsortList[1].Count;
vSort_Count_2 = vsortList[2].Count;
}
bool bwritten = false;
void Generate_Line_List(List<Vector3> vPrint)
{
if (!bwritten)
{
vPrint.Insert(0, tetra_Verts[1]);
vPrint.Add(tetra_Verts[2]);
//vPrint[0] = tetra_Verts[1];
//vPrint[vPrint.Count - 1] = tetra_Verts[2];
for (int i = 0; i < vPrint.Count-1; i++)
{
sLineVectors.Write("new Vector3(" + vPrint[i].x.ToString("F3") + "f, " + vPrint[i].y.ToString("F3") + "f, " + vPrint[i].z.ToString("F3") + "f), " +
"new Vector3(" + vPrint[i+1].x.ToString("F3") + "f, " + vPrint[i+1].y.ToString("F3") + "f, " + vPrint[i+1].z.ToString("F3") + "f), ");
}
Quaternion q;
float angle = 120f;
Vector3 axis = Vector3.up;
q = Quaternion.AngleAxis(angle, axis);
Vector3 vRota;
Vector3 vRota2;
for (int i = 0; i< vPrint.Count-1; i++)
{
vRota = q * vPrint[i];
vRota2 = q * vPrint[i+1];
sLineVectors.Write("new Vector3(" + vRota.x.ToString("F3") + "f, " + vRota.y.ToString("F3") + "f, " + vRota.z.ToString("F3") + "f), " +
"new Vector3(" + vRota2.x.ToString("F3") + "f, " + vRota2.y.ToString("F3") + "f, " + vRota2.z.ToString("F3") + "f), ");
}
angle = 240;
q = Quaternion.AngleAxis(angle, axis);
for (int i = 0; i < vPrint.Count - 1; i++)
{
vRota = q * vPrint[i];
vRota2 = q * vPrint[i + 1];
sLineVectors.Write("new Vector3(" + vRota.x.ToString("F3") + "f, " + vRota.y.ToString("F3") + "f, " + vRota.z.ToString("F3") + "f), " +
"new Vector3(" + vRota2.x.ToString("F3") + "f, " + vRota2.y.ToString("F3") + "f, " + vRota2.z.ToString("F3") + "f), ");
}
/////////////////////////UPPERS//////////////////////
List<Vector3> vlUppers = new List<Vector3>();
axis = tetra_Verts[1].normalized;
angle = 120;
q = Quaternion.AngleAxis(angle, axis);
for (int i = 0; i < vPrint.Count - 1; i++)
{
vRota = q * vPrint[i];
vRota2 = q * vPrint[i + 1];
vlUppers.Add(vRota);
vlUppers.Add(vRota2);
sLineVectors.Write("new Vector3(" + vRota.x.ToString("F3") + "f, " + vRota.y.ToString("F3") + "f, " + vRota.z.ToString("F3") + "f), " +
"new Vector3(" + vRota2.x.ToString("F3") + "f, " + vRota2.y.ToString("F3") + "f, " + vRota2.z.ToString("F3") + "f), ");
}
axis = Vector3.up;
angle = 120;
q = Quaternion.AngleAxis(angle, axis);
for (int i = 0; i < vlUppers.Count - 1; i++)
{
vRota = q * vlUppers[i];
vRota2 = q * vlUppers[i + 1];
sLineVectors.Write("new Vector3(" + vRota.x.ToString("F3") + "f, " + vRota.y.ToString("F3") + "f, " + vRota.z.ToString("F3") + "f), " +
"new Vector3(" + vRota2.x.ToString("F3") + "f, " + vRota2.y.ToString("F3") + "f, " + vRota2.z.ToString("F3") + "f), ");
}
angle = 240;
q = Quaternion.AngleAxis(angle, axis);
for (int i = 0; i < vlUppers.Count - 1; i++)
{
vRota = q * vlUppers[i];
vRota2 = q * vlUppers[i + 1];
sLineVectors.Write("new Vector3(" + vRota.x.ToString("F3") + "f, " + vRota.y.ToString("F3") + "f, " + vRota.z.ToString("F3") + "f), " +
"new Vector3(" + vRota2.x.ToString("F3") + "f, " + vRota2.y.ToString("F3") + "f, " + vRota2.z.ToString("F3") + "f), ");
}
}
sLineVectors.Close();
bwritten = true;
}
void sleeve(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 sector_Foc)
{
Vector3 vCurr;
//v1.y = v2.y = v3.y = 0;
List<Vector3> vInnerLower = new List<Vector3>();
List<Vector3> vInnerUpper = new List<Vector3>();
Vector3 vUp = Vector3.up;
Vector3[] vAlpha = new[] { v1, v2, v3 };
Vector3[] vOmega = new[] { v2, v3, v1 };
float t = 0;
float dt = 1 / 60f;
float d;
float el;
for (int j = 0; j < 3; j++)
{
t = 0;
for (int i = 0; i < 60; i++)
{
vCurr = Sphere_Surf(Vector3.Lerp(vAlpha[j], vOmega[j], t), sector_Foc);
//vCurr.y = 0;
d = vCurr.y;
el = Mathf.Sqrt(tetra_Radius * tetra_Radius - d * d);
//vInnerLower.Add(vCurr + el*vUp);
//vInnerUpper.Add(vCurr - el*vUp);
vInnerLower.Add(vCurr);
vInnerUpper.Add(vCurr - 2f * d * vUp);
t += dt;
}
}
aMD_TT_Sleeve.Add(MeshDraft.Band(vInnerUpper, vInnerLower));
aMD_TT_Sleeve.Add(MeshDraft.Band(vInnerLower, vInnerUpper));
}
Vector3[] vTest = new Vector3[1024];
Vector3[] vTest2 = new Vector3[1024];
int i = 0;
void subdivide_CarbonLine(Vector3 v1, Vector3 v2, Vector3 v3, int depth, Vector3 sector_Foc, int nID, bool bFlipNorm)
{
Vector3 v12, v23, v31;
Vector3 v12_n, v23_n, v31_n;
if (depth == 0)
{
if (bFlipNorm)
{
addTriangle_UV_Tag_CarbonLine(v1, v3, v2, (float)nID);
}
else
{
//if (nID == 1)
//{
// vTest[i] = v1;
// vTest2[i] = v2;
// i++;
//}
addTriangle_UV_Tag_CarbonLine(v1, v2, v3, (float)nID);
}
return;
}
v12 = (v1 + v2) / 2.0f;
v23 = (v2 + v3) / 2.0f;
v31 = (v3 + v1) / 2.0f;
//v12_n = Sphere_Surf(v12, sector_Foc); //sector_Foc
//v23_n = Sphere_Surf(v23, sector_Foc);
//v31_n = Sphere_Surf(v31, sector_Foc);
v12_n = v12; //sector_Foc
v23_n = v23;
v31_n = v31;
/* recursively subdivide new triangles */
subdivide_CarbonLine(v1, v12_n, v31_n, depth - 1, sector_Foc, 1, bFlipNorm);
subdivide_CarbonLine(v12_n, v2, v23_n, depth - 1, sector_Foc, 2, bFlipNorm);
subdivide_CarbonLine(v31_n, v23_n, v3, depth - 1, sector_Foc, 3, bFlipNorm);
subdivide_CarbonLine(v23_n, v31_n, v12_n, depth - 1, sector_Foc, 4, bFlipNorm);
}
private void Create_TETRA_TERREAN(int depth)
{
float scl = scale_TT / 100f;
if (ttType == TT_TYPE.SPHERICAL)
{
subdivide(tetra_Verts[0], tetra_Verts[1], tetra_Verts[2], depth, spheres[0].transform.localPosition, 0, true);
subdivide(tetra_Verts[0], tetra_Verts[2], tetra_Verts[3], depth, spheres[1].transform.localPosition, 1, true);
subdivide(tetra_Verts[0], tetra_Verts[3], tetra_Verts[1], depth, spheres[3].transform.localPosition, 2, true);
subdivide(tetra_Verts[1], tetra_Verts[3], tetra_Verts[2], depth, spheres[2].transform.localPosition, 3, true);
//subdivide(tetra_Verts[0], tetra_Verts[1], tetra_Verts[2], depth, spheres[0].transform.localPosition, 0, false);//Inside
//subdivide(tetra_Verts[0], tetra_Verts[2], tetra_Verts[3], depth, spheres[1].transform.localPosition, 1, false);
//subdivide(tetra_Verts[0], tetra_Verts[3], tetra_Verts[1], depth, spheres[3].transform.localPosition, 2, false);
}
else if(ttType == TT_TYPE.HYPERBOLIC)
{
Vector3[] fc = new Vector3[4];
fc[0] = (tetra_Verts[0] + tetra_Verts[1] + tetra_Verts[2]) / 3f;
fc[1] = (tetra_Verts[0] + tetra_Verts[2] + tetra_Verts[3]) / 3f;
fc[2] = (tetra_Verts[1] + tetra_Verts[3] + tetra_Verts[2]) / 3f;
fc[3] = (tetra_Verts[0] + tetra_Verts[3] + tetra_Verts[1]) / 3f;
beeS[0] = base_Distance * tetra_Radius * fc[0].normalized;
beeS[1] = base_Distance * tetra_Radius * fc[1].normalized;
beeS[2] = base_Distance * tetra_Radius * fc[2].normalized;
beeS[3] = base_Distance * tetra_Radius * fc[3].normalized;
subdivide(tetra_Verts[0], tetra_Verts[1], tetra_Verts[2], depth, fc[0], 0, false);
subdivide(tetra_Verts[0], tetra_Verts[2], tetra_Verts[3], depth, fc[1], 1, false);
subdivide(tetra_Verts[1], tetra_Verts[3], tetra_Verts[2], depth, fc[2], 2, false);
subdivide(tetra_Verts[0], tetra_Verts[3], tetra_Verts[1], depth, fc[3], 3, false);
Scale_Radially();
}
}
private void Scale_Radially()
{
float ratio = 0;
Vector3 v;
float fidx;
float len;
for (int i = 0; i<aMD_TetraTerrean.vertices.Count; i++)
{
fidx = aMD_TetraTerrean.uv[i].x;
ratio = aMD_TetraTerrean.vertices[i].magnitude / tetra_Radius;
aMD_TetraTerrean.vertices[i] *= ((smidge * ratio) + (1 - smidge));
}
}
void subdivide(Vector3 v1, Vector3 v2, Vector3 v3, int depth, Vector3 sector_Foc, int nID, bool bFlipNorm)
{
Vector3 v12, v23, v31;
Vector3 v12_n, v23_n, v31_n;
if (depth == 0)
{
if (ttType == TT_TYPE.SPHERICAL || ttType == TT_TYPE.HYPERBOLIC)
{
if (bFlipNorm)
{
addTriangle_UV_Tag(v1, v3, v2, (float)nID);
}
else
{
addTriangle_UV_Tag(v1, v2, v3, (float)nID);
}
}
else if (ttType == TT_TYPE.OTHER)
{
Extrude_1(v1, v2, v3, nID, sector_Foc);
}
return;
}
v12 = (v1 + v2) / 2.0f;
v23 = (v2 + v3) / 2.0f;
v31 = (v3 + v1) / 2.0f;
//intrude midpoints
if (ttType == TT_TYPE.SPHERICAL)
{
v12_n = Sphere_Surf(v12, sector_Foc); //sector_Foc
v23_n = Sphere_Surf(v23, sector_Foc);
v31_n = Sphere_Surf(v31, sector_Foc);
}
else if(ttType == TT_TYPE.HYPERBOLIC)
{
v12_n = Hyperbolic(v12, sector_Foc); //sector_Foc
v23_n = Hyperbolic(v23, sector_Foc);
v31_n = Hyperbolic(v31, sector_Foc);
}
else if (ttType == TT_TYPE.OTHER)
{
v12_n = Extrude_1(v12, sector_Foc); //sector_Foc
v23_n = Extrude_1(v23, sector_Foc);
v31_n = Extrude_1(v31, sector_Foc);
}
else
{
v12_n = Vector3.zero;
v23_n = Vector3.zero;
v31_n = Vector3.zero;
}
/* recursively subdivide new triangles */
subdivide(v1, v12_n, v31_n, depth - 1, sector_Foc, nID, bFlipNorm);
subdivide(v12_n, v2, v23_n, depth - 1, sector_Foc, nID, bFlipNorm);
subdivide(v31_n, v23_n, v3, depth - 1, sector_Foc, nID, bFlipNorm);
subdivide(v23_n, v31_n, v12_n, depth - 1, sector_Foc, nID, bFlipNorm);
}
private Vector3 Extrude_1(Vector3 vP0, Vector3 sector_Focus)
{
Vector3 l = vP0.normalized;
Vector3 OminC = -sector_Focus;
float rsqr = sphere_Radius * sphere_Radius;
float dotLOminC = Vector3.Dot(l, OminC);
float Omag = OminC.magnitude;
float d = -dotLOminC - Mathf.Sqrt(dotLOminC * dotLOminC - Omag * Omag + sphere_Radius * sphere_Radius);
return (l * d);
}
void addTriangle(Vector3 v0, Vector3 v1, Vector3 v2)
{
aMD_TetraTerrean.Add(MeshDraft.Triangle(v0, v1, v2));
}
void addTriangle_UV_Tag(Vector3 v0, Vector3 v1, Vector3 v2, float uvTag)
{
if (bSeparate_Faces)
{
aMD_tt_Faces[(int)uvTag].Add(MeshDraft.Triangl_UV_Tag(v0, v1, v2, uvTag));
}
else
{
aMD_TetraTerrean.Add(MeshDraft.Triangl_UV_Tag(v0, v1, v2, uvTag));
}
}
void addTriangle_UV_Tag_CarbonLine(Vector3 v0, Vector3 v1, Vector3 v2, float uvTag)
{
aMD_TT_Sleeve.Add(MeshDraft.Triangl_UV_Tag(v0, v1, v2, uvTag));
}
void addTriangle_Skythe(Vector3 v0, Vector3 v1, Vector3 v2, float uvTag)
{
scythe_MD.Add(MeshDraft.Triangl_UV_Tag(v0, v1, v2, uvTag));
}
void addTriangle_UV_Tag_PQUAD(Vector3 v0, Vector3 v1, Vector3 v2, float uvTag)
{
aMD_PQUAD_TMP.Add(MeshDraft.Triangl_UV_Tag(v0, v1, v2, uvTag));
}
public Vector3 GetPointOnBezierCurve(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t)
{
float u = 1f - t;
float t2 = t * t;
float u2 = u * u;
float u3 = u2 * u;
float t3 = t2 * t;
Vector3 result =
(u3) * p0 +
(3f * u2 * t) * p1 +
(3f * u * t2) * p2 +
(t3) * p3;
return result;
}
/// <image url="$(SolutionDir)\EMB\hyperbole.png" scale="0.45"></image>
///
}
/// <image url="$(SolutionDir)\EMB\CD.png" scale="0.16803" />
//int countDown = 10;
//void Update() // Original
//{
// H_Editor_Label.transform.position = tetra_Verts_GO[0].transform.position;
// C_Editor_Label.transform.position = transform.position;
// Vector3 v = (tetra_Verts_GO[0].transform.localPosition + tetra_Verts_GO[1].transform.localPosition + tetra_Verts_GO[2].transform.localPosition) /3;
// I_Editor_Label.transform.position = v + transform.position;
// B_Editor_Label.transform.position = transform.position + base_Distance*tetra_Radius*v.normalized;
// vCHn = (H_Editor_Label.transform.localPosition - C_Editor_Label.transform.localPosition).normalized;
// vIH = (H_Editor_Label.transform.localPosition - I_Editor_Label.transform.localPosition);
// vIHn = vIH.normalized;
// vT1n = Vector3.Dot(vCHn, vIHn) * vIHn;
// vT2n = vCHn;
// T1_Editor_Label.transform.localPosition = (vT1n * tangent_Base * tetra_Radius + B_Editor_Label.transform.localPosition);
// T2_Editor_Label.transform.localPosition = (H_Editor_Label.transform.localPosition - vT2n * tangent_H * tetra_Radius);
// if(frameCount-- == 0 || bPrint_Trace)
// {
// frameCount = 10;
// build_Reference_Hyperbolic_Spline(B_Editor_Label.transform.localPosition, T1_Editor_Label.transform.localPosition,
// T2_Editor_Label.transform.localPosition, H_Editor_Label.transform.localPosition,
// I_Editor_Label.transform.localPosition);
// if(--countDown == 0 || bPrint_Trace)
// {
// Print_Trace(B_Editor_Label.transform.localPosition, T1_Editor_Label.transform.localPosition,
// T2_Editor_Label.transform.localPosition, H_Editor_Label.transform.localPosition,
// I_Editor_Label.transform.localPosition);
// }
// }
// bPrint_Trace = false;
// aMD_Spheres.Clear();
// aMD_Spheres.Add(MeshDraft.Sphere(sphere_Radius, 36, 32));
// cylinder_MD.Clear();
// Set_Tetra_Verts(tetra_Radius);
// float face_dist;
// float tetra_Height;
// Vector3 face_Norm;
// float a, b;
// if (sphere_Radius_Last != sphere_Radius)
// {
// for (int i = 0; i < 4; i++)
// {
// face_dist = face_Centers[i].magnitude;
// tetra_Height = 1.33333f * tetra_Radius;
// a = 2 * Mathf.Sqrt(2) / 3;
// b = Mathf.Sqrt(sphere_Radius * sphere_Radius - tetra_Radius * tetra_Radius * 8f / 9f);
// face_Norm = face_Centers[i].normalized;
// spheres[i].transform.localPosition = face_Norm * (tetra_Radius / 3 + b);
// spheres[i].transform.localRotation = Quaternion.LookRotation(sphere_pos[i]);
// spheres[i].GetComponent<MeshFilter>().mesh = aMD_Spheres.ToMeshInternal();
// tetra_Verts_GO[i].transform.localPosition = tetra_Verts[i];
// }
// }
// sphere_Radius_Last = sphere_Radius;
// tetra_Radius_Last = tetra_Radius;
// //if ((sphere_Radius_Last != sphere_Radius || tetra_Radius_Last != tetra_Radius) && bTetraTerrean_On)
// //{
// aMD_TetraTerrean.Clear();
// for (int i = 0; i < 4; i++)
// {
// aMD_tt_Faces[i].Clear();
// }
// Create_TETRA_TERREAN(all_Shape_Depth);
// if (bSeparate_Faces)
// {
// for (int i = 0; i < 4; i++)
// {
// tt_Faces[i].GetComponent<MeshFilter>().mesh = aMD_tt_Faces[i].ToMeshInternal();
// }
// }
// else
// {
// TetraTerrien_GO.GetComponent<MeshFilter>().mesh = aMD_TetraTerrean.ToMeshInternal();
// TetraTerrien_GO.GetComponent<MeshFilter>().mesh.RecalculateNormals(60);
// }
// aMD_TT_Sleeve.Clear();
// Create_TETRA_TERREAN_Sleeve();
// TT_Sleeve_GO.GetComponent<MeshFilter>().mesh = aMD_TT_Sleeve.ToMeshInternal();
// TT_Sleeve_GO.GetComponent<MeshFilter>().mesh.RecalculateNormals(60);
// sphere_Radius_Last = sphere_Radius;
// tetra_Radius_Last = tetra_Radius;
// if (bSpheresON)
// {
// ShowSpheres(true);
// }
// else
// {
// ShowSpheres(false);
// }
//}
