public static CustomVec3 CalculatePlaneNormal(CustomVec3 a, CustomVec3 b, CustomVec3 c) { var dir = Cross(b - a, c - a); var norm = Normalize(dir); return(norm); }
public static void Normalize(ref CustomVec3 value, out CustomVec3 result) { float factor; Distance(ref value, ref zero, out factor); factor = 1f / factor; result.X = value.X * factor; result.Y = value.Y * factor; result.Z = value.Z * factor; }
public static CustomVec3 Normalize(CustomVec3 vector) { Normalize(ref vector, out vector); return(vector); }
public bool Equals(CustomVec3 other) { return(this == other); }
public static float Dot(CustomVec3 vector1, CustomVec3 vector2) { return(vector1.X * vector2.X + vector1.Y * vector2.Y + vector1.Z * vector2.Z); }
public static void DistanceSquared(ref CustomVec3 value1, ref CustomVec3 value2, out float result) { result = (value1.X - value2.X) * (value1.X - value2.X) + (value1.Y - value2.Y) * (value1.Y - value2.Y) + (value1.Z - value2.Z) * (value1.Z - value2.Z); }
public static void Distance(ref CustomVec3 value1, ref CustomVec3 value2, out float result) { DistanceSquared(ref value1, ref value2, out result); result = (float)Math.Sqrt(result); }
public static void Cross(ref CustomVec3 vector1, ref CustomVec3 vector2, out CustomVec3 result) { result = new CustomVec3(vector1.Y * vector2.Z - vector2.Y * vector1.Z, -(vector1.X * vector2.Z - vector2.X * vector1.Z), vector1.X * vector2.Y - vector2.X * vector1.Y); }
public static CustomVec3 Cross(CustomVec3 vector1, CustomVec3 vector2) { Cross(ref vector1, ref vector2, out vector1); return(vector1); }
public Vertex(CustomVec3 position, int _id, int place) { Source = position; ID = _id; indexAt = place; }
public void DecimateMesh(MeshData meshData) { UnityEngine.Vector3[] verticesArray = meshData.verticesArray; int[][] indicesArray = meshData.indicesArray; int vLen = verticesArray.Length; int tLen = indicesArray[0].Length; if (vLen > 100 && tLen > 0) { CustomVec3[] oldVerices = new CustomVec3[vLen]; for (int i = 0; i < vLen; i++) { UnityEngine.Vector3 temp = verticesArray[i]; oldVerices[i] = (new CustomVec3(temp.x, temp.y, temp.z)); } List <TriangleIdxArray> triangles = new List <TriangleIdxArray>(); if (indicesArray[0] != null) { int i; for (i = 0; i < indicesArray[0].Length; i += 3) { TriangleIdxArray uu = new TriangleIdxArray(); int[] temp = indicesArray[0]; uu.VertexIndex[0] = temp[i]; uu.VertexIndex[1] = temp[i + 1]; uu.VertexIndex[2] = temp[i + 2]; triangles.Add(uu); } } AddVertex(oldVerices); AddFaces(triangles); int cached = Triangles.Length; Generate(); int generatedLenV = Vertices.Length; UnityEngine.Vector3[] vAr = new UnityEngine.Vector3[generatedLenV]; CustomVec3 item; for (int i = 0; i < generatedLenV; i++) { item = Vertices[i].Source; vAr[i] = new UnityEngine.Vector3(item.X, item.Y, item.Z); } int generatedTrilen = Triangles.Length; int[] verticesArr = new int[generatedTrilen * 3]; int localIdx = 0; Vertex[] temp1; for (int i = 0; i < generatedTrilen; i++) { temp1 = Triangles[i].Vertexes; verticesArr[localIdx] = temp1[0].ID; verticesArr[localIdx + 1] = temp1[1].ID; verticesArr[localIdx + 2] = temp1[2].ID; localIdx += 3; } meshData.verticesArray = vAr; meshData.indicesArray[0] = verticesArr; // Precompute arrays from lists meshData.PrepareArrays(); } }
public float ComputeEdgeCollapseCost(Vertex moveFrom, Vertex moveTo) { int i; float edgelength = (moveTo.Source - moveFrom.Source).Length(); float curvature = 0; List <Triangle> sides = new List <Triangle>(); int lenFace = moveFrom.Faces.Count; for (i = 0; i < lenFace; i++) { if (moveFrom.Faces[i].HasVertex(moveTo)) { sides.Add(moveFrom.Faces[i]); } } lenFace = moveFrom.Faces.Count; for (i = 0; i < lenFace; i++) { float mincurv = 1; int lenSide = sides.Count; for (int j = 0; j < lenSide; j++) { float dotprod = CustomVec3.Dot(moveFrom.Faces[i].Normal, sides[j].Normal); // dot product with face normals. '^' defined in vector mincurv = Math.Min(mincurv, (1 - dotprod) / 2.0f); } curvature = Math.Max(curvature, mincurv); } float standardChangeFactor = edgelength * curvature; List <Triangle> adjacentTriangles = new List <Triangle>(); adjacentTriangles.AddRange(moveFrom.Faces); CustomVec3 existingTriangle0; CustomVec3 existingTriangle1; CustomVec3 existingTriangle2; Triangle adjacentTriangle; CustomVec3 newTriangle0; CustomVec3 newTriangle1; CustomVec3 newTriangle2; for (int index = 0; index < adjacentTriangles.Count; index++) { adjacentTriangle = adjacentTriangles[index]; existingTriangle0 = adjacentTriangle.Vertexes[0].Source; existingTriangle1 = adjacentTriangle.Vertexes[1].Source; existingTriangle2 = adjacentTriangle.Vertexes[2].Source; newTriangle0 = adjacentTriangle.Vertexes[0].Source; newTriangle1 = adjacentTriangle.Vertexes[1].Source; newTriangle2 = adjacentTriangle.Vertexes[2].Source; if (existingTriangle0 == moveFrom.Source) { newTriangle0 = moveTo.Source; } if (existingTriangle1 == moveFrom.Source) { newTriangle1 = moveTo.Source; } if (existingTriangle2 == moveFrom.Source) { newTriangle2 = moveTo.Source; } if (Triangle.IsWellFormed(newTriangle0, newTriangle1, newTriangle2)) { CustomVec3 currentFaceNormal = Triangle.ComputeNormal(existingTriangle0, existingTriangle1, existingTriangle2); CustomVec3 newFaceNormal = Triangle.ComputeNormal(newTriangle0, newTriangle1, newTriangle2); if (CustomVec3.Dot(currentFaceNormal, newFaceNormal) == -1) { // Must not let this occur. standardChangeFactor = float.MaxValue; break; } } else { Vertex deletedVertex = null; CustomVec3 sourceFrom = moveFrom.Source; CustomVec3 sourceTo = moveTo.Source; if (newTriangle0 != sourceTo && newTriangle0 != sourceFrom) { deletedVertex = adjacentTriangle.Vertexes[0]; } if (newTriangle1 != sourceTo && newTriangle1 != sourceFrom) { deletedVertex = adjacentTriangle.Vertexes[1]; } if (newTriangle2 != sourceTo && newTriangle2 != sourceFrom) { deletedVertex = adjacentTriangle.Vertexes[2]; } standardChangeFactor += deletedVertex.VertexWeight; } } return(standardChangeFactor); }
public static CustomVec3 ComputeNormal(CustomVec3 v0, CustomVec3 v1, CustomVec3 v2) { return(CustomVec3.CalculatePlaneNormal(v0, v1, v2)); }
public static bool IsWellFormed(CustomVec3 v0, CustomVec3 v1, CustomVec3 v2) { return(v0 != v1 && v1 != v2 && v2 != v0); }
public void ComputeNormal() { Normal = ComputeNormal(Vertexes[0].Source, Vertexes[1].Source, Vertexes[2].Source); }