public void SetColor(Vector4 color) { for (int i = 0; i < mesh.vertices.Length; ++i) { MeshAttr.SetColor(ref mesh.vertices[i], ref color); } }
private bool TooThin(int triangle) { int index = triangle * 3; TVertex v1 = mesh.vertices[indices[index++]]; TVertex v2 = mesh.vertices[indices[index++]]; TVertex v3 = mesh.vertices[indices[index]]; Vector3 e1 = MeshAttr.GetPosition(ref v2) - MeshAttr.GetPosition(ref v1); Vector3 e2 = MeshAttr.GetPosition(ref v3) - MeshAttr.GetPosition(ref v1); Vector3 e3 = MeshAttr.GetPosition(ref v3) - MeshAttr.GetPosition(ref v2); float[] angles = new float[3]; angles[0] = (float)Math.Acos((e2.LengthSquared + e3.LengthSquared - e1.LengthSquared) / (2.0f * e2.Length * e3.Length)); angles[1] = (float)Math.Acos((e1.LengthSquared + e3.LengthSquared - e2.LengthSquared) / (2.0f * e1.Length * e3.Length)); angles[2] = (float)Math.PI - (angles[0] + angles[1]); const float LOWER = (float)Math.PI * 35.0f / 180.0f; const float UPPER = (float)Math.PI * 80.0f / 180.0f; bool tooThin = false; for (int i = 0; i < 3; ++i) { if (angles[i] < LOWER || angles[i] > UPPER) { tooThin = true; break; } } return(tooThin); }
public void AddUVs() { Vector2 uv1 = new Vector2(0, 1); Vector2 uv2 = new Vector2(0.5f, 0.1328f); Vector2 uv3 = new Vector2(1, 1); for (int i = 0; i < indices.Length; i += 3) { MeshAttr.SetUV(ref mesh.vertices[i], ref uv1); MeshAttr.SetUV(ref mesh.vertices[i + 1], ref uv2); MeshAttr.SetUV(ref mesh.vertices[i + 2], ref uv3); } }
private uint GenerateVertex(ref List <TVertex> verts, int a, int b) { Int64 key1 = Geometry.Topology.CreateEdgeKey(indices[a], indices[b]); uint middlePt; if (!subDivideEdgeCache.TryGetValue(key1, out middlePt)) { Vector3 pos1 = MeshAttr.GetPosition(ref mesh.vertices[indices[a]]); Vector3 pos2 = MeshAttr.GetPosition(ref mesh.vertices[indices[b]]); Vector3 e1 = Vector3.Normalize(pos1 + (pos2 - pos1) * 0.5f); TVertex v1 = mesh.vertices[indices[a]]; MeshAttr.SetPosition(ref v1, ref e1); middlePt = (uint)verts.Count; subDivideEdgeCache.Add(key1, middlePt); verts.Add(v1); } return(middlePt); }
/// <summary> /// Adds a triangle with vertex format Position, Normal and UV, calculating the normal from the origin, and /// using a defined UV of top center, bottom left, bottom right. /// </summary> /// <typeparam name="AltVertex"></typeparam> /// <param name="newVerts"></param> /// <param name="newIndices"></param> /// <param name="v1"></param> /// <param name="v2"></param> /// <param name="v3"></param> /// <param name="isAnticlockwise"></param> public void AddTriangle <AltVertex>(ref List <AltVertex> newVerts, ref List <uint> newIndices, ref Vector3 v1, ref Vector3 v2, ref Vector3 v3, bool isAnticlockwise) where AltVertex : struct, IVertex { AltVertex[] triVerts = new AltVertex[3]; triVerts.Initialize(); MeshAttr.SetPosition(ref triVerts[0], ref v1); MeshAttr.SetPosition(ref triVerts[1], ref v2); MeshAttr.SetPosition(ref triVerts[2], ref v3); Vector3 v1N = v1; v1N.Normalize(); for (int i = 0; i < 3; i++) { MeshAttr.SetNormal(ref triVerts[i], ref v1N); } Vector2 uv0 = new Vector2(0.5f, 1); Vector2 uv1 = new Vector2(0, 0); Vector2 uv2 = new Vector2(1, 0); MeshAttr.SetUV(ref triVerts[0], ref uv0); MeshAttr.SetUV(ref triVerts[1], ref uv1); MeshAttr.SetUV(ref triVerts[2], ref uv2); int index = newVerts.Count; for (int i = 0; i < 3; i++) { newVerts.Add(triVerts[i]); } if (isAnticlockwise) { newIndices.Add((uint)index); newIndices.Add((uint)index + 1); newIndices.Add((uint)index + 2); } else { newIndices.Add((uint)index); newIndices.Add((uint)index + 2); newIndices.Add((uint)index + 1); } }
private bool IsObtuse(int triangle) { int index = triangle * 3; TVertex v1 = mesh.vertices[indices[index++]]; TVertex v2 = mesh.vertices[indices[index++]]; TVertex v3 = mesh.vertices[indices[index]]; Vector3 e1 = MeshAttr.GetPosition(ref v2) - MeshAttr.GetPosition(ref v1); Vector3 e2 = MeshAttr.GetPosition(ref v3) - MeshAttr.GetPosition(ref v1); Vector3 e3 = MeshAttr.GetPosition(ref v3) - MeshAttr.GetPosition(ref v2); float l1Sq = e1.LengthSquared; float l2Sq = e2.LengthSquared; float l3Sq = e3.LengthSquared; if (l1Sq + l2Sq < l3Sq || l1Sq + l3Sq < l2Sq || l2Sq + l3Sq < l1Sq) { return(true); } return(false); }
/// <summary> /// Adds a triangle based on the current mesh with the vertex format Position, Normal, UV and Color. /// It sets the normal for each vertex to the original position vector, /// UV is set to top center, bottom left, bottom right, with original vert being top center /// It sets color of all verts to the color of the original vertex. /// </summary> /// <typeparam name="AltVertex"></typeparam> /// <param name="newVerts">The new set of vertices</param> /// <param name="newIndices">The new set of indices</param> /// <param name="v1index">The index of the vertex in the original mesh</param> /// <param name="v2">the position of the first new vertex</param> /// <param name="v3">the position of the second new vertex</param> /// <param name="color">The new vertex color</param>" public void AddTriangle2 <AltVertex>(ref List <AltVertex> newVerts, ref List <uint> newIndices, int v1index, ref Vector3 v2, ref Vector3 v3, Vector4 color) where AltVertex : struct, IVertex { AltVertex[] triVerts = new AltVertex[3]; triVerts.Initialize(); Vector3 v1Pos = MeshAttr.GetPosition(ref mesh.vertices[v1index]); MeshAttr.SetPosition(ref triVerts[0], ref v1Pos); MeshAttr.SetPosition(ref triVerts[1], ref v2); MeshAttr.SetPosition(ref triVerts[2], ref v3); v1Pos.Normalize(); for (int i = 0; i < 3; i++) { MeshAttr.SetNormal(ref triVerts[i], ref v1Pos); } Vector2 uv0 = new Vector2(0.5f, 1); Vector2 uv1 = new Vector2(0, 0); Vector2 uv2 = new Vector2(1, 0); MeshAttr.SetUV(ref triVerts[0], ref uv0); MeshAttr.SetUV(ref triVerts[1], ref uv1); MeshAttr.SetUV(ref triVerts[2], ref uv2); MeshAttr.SetColor(ref triVerts[0], ref color); MeshAttr.SetColor(ref triVerts[1], ref color); MeshAttr.SetColor(ref triVerts[2], ref color); newVerts[v1index] = triVerts[0]; int index = newVerts.Count; newVerts.Add(triVerts[1]); newVerts.Add(triVerts[2]); newIndices.Add((uint)v1index); newIndices.Add((uint)index++); newIndices.Add((uint)index++); }
public void AddNormals() { // TODO Currently assuming that we are using triangles, and have // maximised the vertices. if (mesh.vertices[0].GetType().GetInterface("INormalVertex") != null) { for (int i = 0; i < indices.Length; i += 3) { Vector3 pos1 = MeshAttr.GetPosition(ref mesh.vertices[i]); Vector3 pos2 = MeshAttr.GetPosition(ref mesh.vertices[i + 1]); Vector3 pos3 = MeshAttr.GetPosition(ref mesh.vertices[i + 2]); Vector3 a = pos2 - pos1; Vector3 b = pos3 - pos1; Vector3 normal = Vector3.Cross(a, b); normal.Normalize(); MeshAttr.SetNormal(ref mesh.vertices[i], ref normal); MeshAttr.SetNormal(ref mesh.vertices[i + 1], ref normal); MeshAttr.SetNormal(ref mesh.vertices[i + 2], ref normal); } } }
public IGeometry ClonePosition <TVertex2>() where TVertex2 : struct, IVertex { TVertex2[] newVerts = new TVertex2[mesh.vertices.Length]; int index = 0; foreach (var iter in mesh.vertices) { TVertex vertex = iter; Vector3 pos = MeshAttr.GetPosition(ref vertex); newVerts[index] = new TVertex2(); MeshAttr.SetPosition(ref newVerts[index], ref pos); index++; } Mesh <TVertex2> newMesh = new Mesh <TVertex2>(newVerts); Indices newIndices = null; if (indices != null) { newIndices = indices.Clone(); } Geometry <TVertex2> newGeom = new Geometry <TVertex2>(newMesh, newIndices); return(newGeom); }
public float RelaxTriangles(float multiplier) { NeedsUpdate = true; double totalSurfaceArea = 4.0 * Math.PI; double idealFaceArea = totalSurfaceArea / (indices.Length / 3); double idealEdgeLength = Math.Sqrt(idealFaceArea * 4.0 / Math.Sqrt(3.0)); double idealDistanceToCentroid = idealEdgeLength * Math.Sqrt(3) / 3.0 * 0.9; Vector3[] shiftPositions = new Vector3[mesh.vertices.Length]; for (int i = 0; i < mesh.vertices.Length; ++i) { shiftPositions[i] = new Vector3(Vector3.Zero); } int numIndices = indices.Length; TVertex[] centroidVerts = new TVertex[numIndices / 3]; TVertex centroidVertex = new TVertex(); for (int i = 0; i < numIndices; i += 3) { Vector3 centroid = Topology.CalculateCentroid(i / 3); centroid.Normalize(); MeshAttr.SetPosition(ref centroidVertex, ref centroid); Vector3[] oldPositions = new Vector3[3] { new Vector3(MeshAttr.GetPosition(ref mesh.vertices[indices[i]])), new Vector3(MeshAttr.GetPosition(ref mesh.vertices[indices[i + 1]])), new Vector3(MeshAttr.GetPosition(ref mesh.vertices[indices[i + 2]])), }; for (int j = 0; j < 3; ++j) { Vector3 midLine = centroid - oldPositions[j]; float midLength = midLine.Length; midLine *= (float)(multiplier * (midLength - idealDistanceToCentroid) / midLength); shiftPositions[indices[i + j]] += midLine; } } var origin = Vector3.Zero; Plane p = new Plane(Vector3.UnitY, Vector3.Zero); for (int i = 0; i < mesh.vertices.Length; ++i) { Vector3 vertexPosition = MeshAttr.GetPosition(ref mesh.vertices[i]); p.Redefine(vertexPosition, origin); shiftPositions[i] = vertexPosition + p.ProjectPoint(shiftPositions[i]); shiftPositions[i].Normalize(); } // Stop poylgons rotating about their centroid. // Doesn't stop triangles flipping. float[] rotationSuppressions = new float[mesh.vertices.Length]; rotationSuppressions.Initialize(); Topology.GenerateEdges(); float minEdgeLength = (float)idealEdgeLength * 0.8f; float maxEdgeLength = (float)idealEdgeLength * 1.2f; foreach (var iter in Topology.Edges) { Int64 key = iter.Key; int index1 = (int)(key & 0xffffffff); int index2 = (int)((key >> 32) & 0xffffffff); Vector3 oldPos1 = MeshAttr.GetPosition(ref mesh.vertices[index1]); Vector3 oldPos2 = MeshAttr.GetPosition(ref mesh.vertices[index2]); Vector3 newPos1 = shiftPositions[index1]; Vector3 newPos2 = shiftPositions[index2]; Vector3 oldEdge = oldPos2 - oldPos1; Vector3 newEdge = newPos2 - newPos1; if (newEdge.Length < minEdgeLength) { // Move shift positions back out to ensure that the edge is never too small. Vector3 midPt = newPos1 + 0.5f * newEdge; newEdge.Normalize(); newEdge *= minEdgeLength * 0.5f; shiftPositions[index1] = midPt - newEdge; shiftPositions[index2] = midPt + newEdge; newEdge = shiftPositions[index2] - shiftPositions[index1]; } if (newEdge.Length > maxEdgeLength) { // Move shift positions back in to ensure that the edge is never too large. Vector3 midPt = newPos1 + 0.5f * newEdge; newEdge.Normalize(); newEdge *= (maxEdgeLength * 0.5f); shiftPositions[index1] = midPt - newEdge; shiftPositions[index2] = midPt + newEdge; newEdge = shiftPositions[index2] - shiftPositions[index1]; } oldEdge.Normalize(); newEdge.Normalize(); float suppression = (1.0f - Vector3.Dot(oldEdge, newEdge)) * 0.5f; rotationSuppressions[index1] = Math.Max(suppression, rotationSuppressions[index1]); rotationSuppressions[index2] = Math.Max(suppression, rotationSuppressions[index2]); } for (int i = 0; i < mesh.vertices.Length; ++i) { Vector3 pos = MeshAttr.GetPosition(ref mesh.vertices[i]); Vector3 delta = pos; pos = Math2.Lerp(pos, shiftPositions[i], (float)(1.0f - Math.Sqrt(rotationSuppressions[i]))); pos.Normalize(); shiftPositions[i] = pos; } float totalShift = 0; for (int i = 0; i < mesh.vertices.Length; ++i) { Vector3 delta = MeshAttr.GetPosition(ref mesh.vertices[i]); MeshAttr.SetPosition(ref mesh.vertices[i], ref shiftPositions[i]); delta -= shiftPositions[i]; totalShift += delta.Length; } Topology.Regenerate(); return(totalShift); }
public Vector4 GetColor(int index) { return(MeshAttr.GetColor(ref vertices[index])); }
public Vector3 GetNormal(int index) { return(MeshAttr.GetNormal(ref vertices[index])); }
public void SetNormal(int index, ref Vector3 normal) { MeshAttr.SetNormal(ref vertices[index], ref normal); }
public Vector3 GetPosition(int index) { return(MeshAttr.GetPosition(ref vertices[index])); }
public void SetPosition(int index, ref Vector3 position) { MeshAttr.SetPosition(ref vertices[index], ref position); }
public void TweakTriangles(float ratio, Random rand) { NeedsUpdate = true; // Assumptions: minimised mesh. Shared edges won't work without shared verts. Topology.GenerateEdges(); // How many edges do we have? exchange some percentage of them... int numPerturbations = (int)((float)Topology.Edges.Count * ratio); int numTriangles = mesh.vertices.Length; List <Int64> keys = new List <Int64>(Topology.Edges.Keys); List <int> visitedTris = new List <int>(); for (int i = 0; i < numPerturbations; ++i) { // Choose a random edge: int edgeIndex = rand.Next(Topology.Edges.Count); // Check out the tris around the edge. Int64 key = keys[edgeIndex]; Edge edge = Topology.Edges[key]; // TODO - add flag to triangle to avoid n2/2 lookup. bool r = false; foreach (var visited in visitedTris) { if (edge.triangle1 == visited || edge.triangle2 == visited) { r = true; break; } } if (r) { continue; } visitedTris.Add(edge.triangle1); visitedTris.Add(edge.triangle2); if (IsObtuse(edge.triangle1) || IsObtuse(edge.triangle2)) { continue; } uint index1 = (uint)(key & 0xffffffff); uint index2 = (uint)((key >> 32) & 0xffffffff); uint index3; uint index4; uint a = index1; int cornerA = GetTriOffset(edge.triangle1, a); // get the next coord in the triangle (in ccw order) uint b = indices[edge.triangle1 * 3 + ((cornerA + 1) % 3)]; uint c = indices[edge.triangle1 * 3 + ((cornerA + 2) % 3)]; uint d = 0; if (b == index2) { d = indices[edge.triangle2 * 3 + ((GetTriOffset(edge.triangle2, a) + 1) % 3)]; index3 = c; index4 = d; } else { d = indices[edge.triangle2 * 3 + ((GetTriOffset(edge.triangle2, a) + 2) % 3)]; index3 = b; index4 = d; } if (Topology.TrianglesPerVertex[index1] <= 5 || Topology.TrianglesPerVertex[index2] <= 5 || Topology.TrianglesPerVertex[index3] >= 7 || Topology.TrianglesPerVertex[index4] >= 7) { continue; } // Check edge lengths Vector3 pos1 = MeshAttr.GetPosition(ref mesh.vertices[index1]); Vector3 pos2 = MeshAttr.GetPosition(ref mesh.vertices[index2]); Vector3 pos3 = MeshAttr.GetPosition(ref mesh.vertices[index3]); Vector3 pos4 = MeshAttr.GetPosition(ref mesh.vertices[index4]); float oldLength = new Vector3(pos2 - pos1).Length; float newLength = new Vector3(pos4 - pos3).Length; if (oldLength / newLength >= 2 || oldLength / newLength <= 0.5f) { continue; } Topology.TrianglesPerVertex[index1]--; Topology.TrianglesPerVertex[index2]--; Topology.TrianglesPerVertex[index3]++; Topology.TrianglesPerVertex[index4]++; // Need to keep tris in CCW order. if (b == index2) { // order is a b c; c is the non-shared vertex. // new tris are: ADC, DBC // tri2 order is a d b indices[edge.triangle1 * 3] = a; indices[edge.triangle1 * 3 + 1] = d; indices[edge.triangle1 * 3 + 2] = c; indices[edge.triangle2 * 3] = d; indices[edge.triangle2 * 3 + 1] = b; indices[edge.triangle2 * 3 + 2] = c; } else { // order is a b c; b is the non-shared value // new tris are ACD, CBD // tri2 order is a b d indices[edge.triangle1 * 3] = a; indices[edge.triangle1 * 3 + 1] = b; indices[edge.triangle1 * 3 + 2] = d; indices[edge.triangle2 * 3] = c; indices[edge.triangle2 * 3 + 1] = d; indices[edge.triangle2 * 3 + 2] = b; } } Topology.Regenerate(); }
// Alternative algorithm // for each triangle // find normal // find centroid radius // Tilt triangle towards centroid radius // moving edges towards symmetry. // generate new point for each tri vert // for each vert, calc average of all new verts, normalise and apply // Algorithm is nearly there, but on some triangles, there is a potential that converging on // centroid tilts through random moves away from centroidal radius, and they become thin / start overlapping. public float RelaxTriangles1(float multiplier) { NeedsUpdate = true; double totalSurfaceArea = 4.0 * Math.PI; double idealFaceArea = totalSurfaceArea / (indices.Length / 3); double idealEdgeLength = Math.Sqrt(idealFaceArea * 4.0 / Math.Sqrt(3.0)); double idealDistanceToCentroid = idealEdgeLength * Math.Sqrt(3) / 3.0 * 0.9; int numIndices = indices.Length; Vector3[] shiftPositions = new Vector3[mesh.vertices.Length]; for (int i = 0; i < mesh.vertices.Length; ++i) { shiftPositions[i] = new Vector3(Vector3.Zero); } for (int i = 0; i < numIndices; i += 3) { if (1 == 1)//TooThin(i)) { Vector3 centroid = Topology.CalculateCentroid(i / 3); centroid.Normalize(); // Compare each corner to the centroid // if too far off some ideal length ( the centroid of an equilateral triangle ), // pull vertex closer to centroid, (without buggering up the other triangles using // this point.) Vector3[] oldPositions = new Vector3[3] { new Vector3(MeshAttr.GetPosition(ref mesh.vertices[indices[i]])), new Vector3(MeshAttr.GetPosition(ref mesh.vertices[indices[i + 1]])), new Vector3(MeshAttr.GetPosition(ref mesh.vertices[indices[i + 2]])), }; Vector3[] newPositions = new Vector3[3]; for (int j = 0; j < 3; ++j) { TVertex v1 = mesh.vertices[indices[i + j]]; Vector3 v1Pos = MeshAttr.GetPosition(ref v1); Vector3 e1 = centroid - v1Pos; if (e1.Length > idealDistanceToCentroid * 1.1) { // Move vertex closer to centroid float factor = 1.0f - (float)idealDistanceToCentroid / e1.Length; float fraction = (multiplier * (1.0f - (float)idealDistanceToCentroid / e1.Length)); factor = factor * fraction; v1Pos = Vector3.Normalize(v1Pos + e1 * factor); } else if (e1.Length < idealDistanceToCentroid * 0.9) { // Move vertex away from the centroid float factor = 1 - e1.Length / (float)idealDistanceToCentroid; float fraction = (multiplier * (e1.Length / (float)idealDistanceToCentroid)); factor = factor * fraction; v1Pos = Vector3.Normalize(v1Pos - e1 * factor); } newPositions[j] = v1Pos; } // If this makes the triangle less parallel to the sphere, don't do it. Vector3 a = newPositions[1] - newPositions[0]; Vector3 b = newPositions[2] - newPositions[1]; Vector3 normal = Vector3.Cross(a, b); normal.Normalize(); float dot = Vector3.Dot(centroid, normal); double phi = Math.Acos(dot); a = oldPositions[1] - oldPositions[0]; b = oldPositions[2] - oldPositions[1]; normal = Vector3.Cross(a, b); normal.Normalize(); dot = Vector3.Dot(centroid, normal); double theta = Math.Acos(dot); if (phi < dot) { for (int j = 0; j < 3; ++j) { //SetPosition(ref mesh.vertices[indices[i + j]], ref newPositions[j]); shiftPositions[indices[i + j]] = newPositions[j]; } } // If any surrounding triangles would be less parallel to the sphere than // this is more parallel, don't do it. } } TVertex[] vertices = new TVertex[mesh.vertices.Length]; float totalShift = 0; for (int i = 0; i < mesh.vertices.Length; ++i) { Vector3 delta = shiftPositions[i] - MeshAttr.GetPosition(ref mesh.vertices[i]); MeshAttr.SetPosition(ref mesh.vertices[i], ref shiftPositions[i]); totalShift += delta.Length; } Topology.Regenerate(); return(totalShift); }
public Geometry <AltVertex> GenerateBorderGeometry <AltVertex>() where AltVertex : struct, IVertex { if (borders == null || borders.Count == 0) { return(null); } else { List <AltVertex> vertices = new List <AltVertex>(); List <uint> newIndices = new List <uint>(); const float h = 0.1f; foreach (var iter in borders) { Int64 borderKey = iter.Key; int v1index = (int)(borderKey & 0xffffffff); int v2index = (int)((borderKey >> 32) & 0xffffffff); Border border = iter.Value; // The border lies along an edge in the dual geometry. int plateIndex1 = border.plate0; int plateIndex2 = border.plate1; Vector3 v1Pos = geometry.Mesh.GetPosition(v1index); Vector3 v2Pos = geometry.Mesh.GetPosition(v2index); Vector3 centroid1 = geometry.Topology.Centroids[border.c1Index].position; Vector3 centroid2 = geometry.Topology.Centroids[border.c2Index].position; Vector3 v1g1prime = Math2.BaseProjection(v1Pos, centroid1, centroid2, h); Vector3 v1g2prime = Math2.BaseProjection(v1Pos, centroid2, centroid1, h); Vector3 v2g1prime = Math2.BaseProjection(v2Pos, centroid1, centroid2, h); Vector3 v2g2prime = Math2.BaseProjection(v2Pos, centroid2, centroid1, h); centroid1 *= 1.01f; // Project the centroids out of the sphere slightly centroid2 *= 1.01f; bool edgeOrderIsAnticlockwise = false; for (int i = 0; i < 3; i++) { if (geometry.Indices[border.c1Index * 3 + i] == v1index) { if (geometry.Indices[border.c1Index * 3 + (i + 1) % 3] == v2index) { edgeOrderIsAnticlockwise = true; } break; } } int index = vertices.Count; geometry.AddTriangle(ref vertices, ref newIndices, ref v1g2prime, ref centroid2, ref centroid1, edgeOrderIsAnticlockwise); geometry.AddTriangle(ref vertices, ref newIndices, ref v1g2prime, ref centroid1, ref v1g1prime, edgeOrderIsAnticlockwise); geometry.AddTriangle(ref vertices, ref newIndices, ref v2g1prime, ref centroid1, ref centroid2, edgeOrderIsAnticlockwise); geometry.AddTriangle(ref vertices, ref newIndices, ref v2g1prime, ref centroid2, ref v2g2prime, edgeOrderIsAnticlockwise); float p1 = Math2.Clamp(Math.Abs(borderCorners[border.c1Index].stress.pressure) * 1000.0f, 0, 1.0f); float p2 = Math2.Clamp(Math.Abs(borderCorners[border.c2Index].stress.pressure) * 1000.0f, 0, 1.0f); float hue1 = borderCorners[border.c1Index].stress.pressure > 0 ? 0 : 0.5f; float hue2 = borderCorners[border.c2Index].stress.pressure > 0 ? 0 : 0.5f; Vector3 rgb1 = Math2.HSV2RGB(new Vector3(hue1, p1, 1.0f - p1)); Vector3 rgb2 = Math2.HSV2RGB(new Vector3(hue2, p2, 1.0f - p2)); Vector4 c1Color = new Vector4(rgb1.X, rgb1.Y, rgb1.Z, 1); Vector4 c2Color = new Vector4(rgb2.X, rgb2.Y, rgb2.Z, 1); AltVertex v; for (int i = 0; i < 12; ++i) { Vector4 color = new Vector4(1.0f, 1.0f, 1.0f, 1.0f); if (i == 0 || i == 1 || i == 3 || i == 8 || i == 10 || i == 11) { color = c2Color; } else if (i == 2 || i == 4 || i == 5 || i == 6 || i == 7 || i == 9) { color = c1Color; } v = vertices[index + i]; MeshAttr.SetColor(ref v, ref color); vertices[index + i] = v; } } Mesh <AltVertex> newMesh = new Mesh <AltVertex>(vertices.ToArray()); return(new Geometry <AltVertex>(newMesh, newIndices.ToArray())); } }
public void SetColor(int index, ref Vector4 color) { MeshAttr.SetColor(ref vertices[index], ref color); }