private void model1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { if (e.LeftButton == MouseButtonState.Pressed) { int selEntityIndex = model1.GetEntityUnderMouseCursor(devDept.Graphics.RenderContextUtility.ConvertPoint(model1.GetMousePosition(e))); if (selEntityIndex != -1) { Entity entity = model1.Entities[selEntityIndex]; Point3D pt; int tri; try { if (model1.FindClosestTriangle((IFace)entity, devDept.Graphics.RenderContextUtility.ConvertPoint(model1.GetMousePosition(e)), out pt, out tri) > 0) { IndexTriangle it = ((Mesh)entity).Triangles[tri]; // calculates normal direction of selected triangle Point3D[] pointEnt = ((Mesh)entity).Vertices; Triangle selT = new Triangle(pointEnt[it.V1], pointEnt[it.V2], pointEnt[it.V3]); selT.Regen(0.1); Sh.Direction = selT.Normal; // shows the normal's direction like an arrow Sh.DrawNormalDirection(pt, _readFile.Entities[_originalIndex].BoxSize.Diagonal); model1.Entities.Regen(); model1.Invalidate(); } } catch { } } } }
protected override bool AllVerticesInFrustum(FrustumParams data) { // Computes the triangles that are completely enclosed to the selection rectangle if (vp.processVisibleOnly && !Selected) { return(false); } SelectedSubItems = new List <int>(); for (int i = 0; i < Triangles.Length; i++) { IndexTriangle tri = Triangles[i]; if (Camera.IsInFrustum(Vertices[tri.V1], data.Frustum) && Camera.IsInFrustum(Vertices[tri.V2], data.Frustum) && Camera.IsInFrustum(Vertices[tri.V3], data.Frustum)) { SelectedSubItems.Add(i); } } UpdateCompileSelection(); return(false); }
/// <summary> /// Splits yellow triangles in red/blue section considering the smoothingAngle. /// </summary> private void ReassingYellowTriangles(Mesh originalEntity, Vector3D direction, MyIndexTriangle[] originalT, LinkedList <SharedEdge>[] sell, Mesh redSection, Mesh yellowSection, Mesh blueSection, int[] redPoints, int[] yellowPoints, int[] bluePoints, ref int redT, ref int yellowT, ref int blueT) { for (int i = 0; i < originalT.Length; i++) { if (yellowSection.Triangles[i] != null) { //if is a perfect vertical triangle from direction must be yellow double angle = Vector3D.AngleBetween(direction, originalT[i].Normal); if (angle != Math.PI / 2) { IndexTriangle it = yellowSection.Triangles[i]; // gets group of triangle i considering his SharedEdges var result = 0; originalT[i].Group = result = GetFinalDraftTriangles(originalT, sell, i, originalEntity.Vertices); if (result > 0) { //Triangle move from yellow group to red group redT++; yellowT--; redSection.Triangles[i] = (IndexTriangle)it.Clone(); blueSection.Triangles[i] = null; yellowSection.Triangles[i] = null; redPoints[it.V3] = redPoints[it.V2] = redPoints[it.V1] = 1; yellowPoints[it.V1] = yellowPoints[it.V2] = yellowPoints[it.V3] = 0; } else if (result < 0) { //Triangle move from yellow group to blue group blueT++; yellowT--; blueSection.Triangles[i] = (IndexTriangle)it.Clone(); redSection.Triangles[i] = null; yellowSection.Triangles[i] = null; bluePoints[it.V3] = bluePoints[it.V2] = bluePoints[it.V1] = 1; yellowPoints[it.V1] = yellowPoints[it.V2] = yellowPoints[it.V3] = 0; } // Checks if some Triangles was near to this(ReVisit = true) and sets to the same group for (int j = 0; j < originalT.Length; j++) { if (originalT[j].Group == 0 && originalT[j].ReVisit) { if (originalT[i].Group != 0) { originalT[j].Group = originalT[i].Group; originalT[j].ReVisit = false; } } } } } } }
protected override void DrawForSelection(GfxDrawForSelectionParams data) { if (DrawSubItemsForSelection) { var prev = vp.SuspendSetColorForSelection; vp.SuspendSetColorForSelection = false; // Draws the triangles with the color-coding needed for visibility computation for (int index = 0; index < selectedSubItems.Count; index++) { //draws only the triangles with normals directions towards the Camera int i = selectedSubItems[index]; Point3D p1 = Vertices[Triangles[i].V1]; Point3D p2 = Vertices[Triangles[i].V2]; Point3D p3 = Vertices[Triangles[i].V3]; double[] u = new[] { p1.X - p3.X, p1.Y - p3.Y, p1.Z - p3.Z }; double[] v = new[] { p2.X - p1.X, p2.Y - p1.Y, p2.Z - p1.Z }; // cross product Vector3D Normal = new Vector3D(u[1] * v[2] - u[2] * v[1], u[2] * v[0] - u[0] * v[2], u[0] * v[1] - u[1] * v[0]); Normal.Normalize(); if (Vector3D.Dot(vp.Camera.NearPlane.AxisZ, Normal) <= 0) { continue; } vp.SetColorDrawForSelection(i); IndexTriangle tri = Triangles[i]; data.RenderContext.DrawTriangles(new Point3D[] { Vertices[tri.V1], Vertices[tri.V2], Vertices[tri.V3], }, Vector3D.AxisZ); } vp.SuspendSetColorForSelection = prev; // reset the color to avoid issues with the entities drawn after this one data.RenderContext.SetColorWireframe(System.Drawing.Color.White); } else { base.DrawForSelection(data); } }
public Floor(bool multitexture) : base(4, 2, Mesh.natureType.RichPlain) { this.multiTexture = multitexture; Vertices[0] = new Point3D(-width * 0.5, height * 0.5); Vertices[1] = new Point3D(width * 0.5, height * 0.5); Vertices[2] = new Point3D(width * 0.5, -height * 0.5); Vertices[3] = new Point3D(-width * 0.5, -height * 0.5); Triangles[0] = new IndexTriangle(0, 1, 2); Triangles[1] = new IndexTriangle(0, 2, 3); }
public static int GetPrimitiveSize(PrimitiveType primitive) { switch (primitive) { case PrimitiveType.LineList: return(IndexLine.GetSizeInShortInts()); case PrimitiveType.PointList: return(IndexPoint.GetSizeInShortInts()); case PrimitiveType.TriangleList: return(IndexTriangle.GetSizeInShortInts()); default: break; } return(IndexTriangle.GetSizeInShortInts()); }
protected static IndexBuffer ToTrianglesBuffer ( Rhino.Geometry.Mesh mesh, Primitive.Part part, out int triangleCount ) { triangleCount = part.FaceCount; { var faces = mesh.Faces; for (int f = part.StartFaceIndex; f < part.EndFaceIndex; ++f) { if (faces[f].IsQuad) { triangleCount++; } } } if (triangleCount > 0) { var ib = new IndexBuffer(triangleCount * IndexTriangle.GetSizeInShortInts()); ib.Map(triangleCount * IndexTriangle.GetSizeInShortInts()); using (var istream = ib.GetIndexStreamTriangle()) { var faces = mesh.Faces; for (int f = part.StartFaceIndex; f < part.EndFaceIndex; ++f) { var face = faces[f]; istream.AddTriangle(new IndexTriangle(face.A - part.StartVertexIndex, face.B - part.StartVertexIndex, face.C - part.StartVertexIndex)); if (face.IsQuad) { istream.AddTriangle(new IndexTriangle(face.C - part.StartVertexIndex, face.D - part.StartVertexIndex, face.A - part.StartVertexIndex)); } } } ib.Unmap(); return(ib); } return(null); }
// Create and populate a pair of vertex and index buffers. Also update parameters associated with the format of the vertices. private void ProcessTriangles(RenderingPassBufferStorage bufferStorage) { List <TriangleInfo> triangles = bufferStorage.Triangles; if (triangles.Count == 0) { return; } bool useNormals = this.Inputs.EnableFaceNormal; // Vertex attributes are stored sequentially in vertex buffers. The attributes can include position, normal vector, and color. // All vertices within a vertex buffer must have the same format. Possible formats are enumerated by VertexFormatBits. // Vertex format also determines the type of rendering effect that can be used with the vertex buffer. In this sample, // the color is always encoded in the vertex attributes. bufferStorage.FormatBits = useNormals ? VertexFormatBits.PositionNormalColored : VertexFormatBits.PositionColored; // The format of the vertices determines the size of the vertex buffer. int vertexBufferSizeInFloats = (useNormals ? VertexPositionNormalColored.GetSizeInFloats() : VertexPositionColored.GetSizeInFloats()) * bufferStorage.VertexBufferCount; bufferStorage.VertexBuffer = new VertexBuffer(vertexBufferSizeInFloats); bufferStorage.VertexBuffer.Map(vertexBufferSizeInFloats); int numTriangles = triangles.Count; if (useNormals) { // A VertexStream is used to write data into a VertexBuffer. VertexStreamPositionNormalColored vertexStream = bufferStorage.VertexBuffer.GetVertexStreamPositionNormalColored(); for (int i = 0; i < numTriangles; i++) { var triangleInfo = triangles[i]; g3.Triangle3d triangle = triangleInfo.Triangle; vertexStream.AddVertex(new VertexPositionNormalColored(triangle.V0.ToXYZ() + triangleInfo.Offset, triangleInfo.Normal, triangleInfo.ColorWithTransparency)); vertexStream.AddVertex(new VertexPositionNormalColored(triangle.V1.ToXYZ() + triangleInfo.Offset, triangleInfo.Normal, triangleInfo.ColorWithTransparency)); vertexStream.AddVertex(new VertexPositionNormalColored(triangle.V2.ToXYZ() + triangleInfo.Offset, triangleInfo.Normal, triangleInfo.ColorWithTransparency)); } } else { // A VertexStream is used to write data into a VertexBuffer. VertexStreamPositionColored vertexStream = bufferStorage.VertexBuffer.GetVertexStreamPositionColored(); for (int i = 0; i < numTriangles; i++) { var triangleInfo = triangles[i]; g3.Triangle3d triangle = triangleInfo.Triangle; // make the color of all faces white in HLR ColorWithTransparency color = triangleInfo.ColorWithTransparency; vertexStream.AddVertex(new VertexPositionColored(triangle.V0.ToXYZ() + triangleInfo.Offset, color)); vertexStream.AddVertex(new VertexPositionColored(triangle.V1.ToXYZ() + triangleInfo.Offset, color)); vertexStream.AddVertex(new VertexPositionColored(triangle.V2.ToXYZ() + triangleInfo.Offset, color)); } } bufferStorage.VertexBuffer.Unmap(); // Primitives are specified using a pair of vertex and index buffers. An index buffer contains a sequence of indices into // the associated vertex buffer, each index referencing a particular vertex. bufferStorage.IndexBufferCount = bufferStorage.PrimitiveCount * IndexTriangle.GetSizeInShortInts(); int indexBufferSizeInShortInts = 1 * bufferStorage.IndexBufferCount; bufferStorage.IndexBuffer = new IndexBuffer(indexBufferSizeInShortInts); bufferStorage.IndexBuffer.Map(indexBufferSizeInShortInts); // An IndexStream is used to write data into an IndexBuffer. IndexStreamTriangle indexStream = bufferStorage.IndexBuffer.GetIndexStreamTriangle(); int currIndex = 0; for (int i = 0; i < numTriangles; i++) { // Add three indices that define a triangle. indexStream.AddTriangle(new IndexTriangle(currIndex + 0, currIndex + 1, currIndex + 2)); currIndex += 3; } bufferStorage.IndexBuffer.Unmap(); // VertexFormat is a specification of the data that is associated with a vertex (e.g., position). bufferStorage.VertexFormat = new VertexFormat(bufferStorage.FormatBits); // Effect instance is a specification of the appearance of geometry. For example, it may be used to specify color, if there is no color information provided with the vertices. bufferStorage.EffectInstance = new EffectInstance(bufferStorage.FormatBits); }
// Create and populate a pair of vertex and index buffers. Also update parameters associated with the format of the vertices. private void ProcessFaces(RenderingPassBufferStorage bufferStorage) { List <MeshInfo> meshes = bufferStorage.Meshes; if (meshes.Count == 0) { return; } List <int> numVerticesInMeshesBefore = new List <int>(); bool useNormals = this.Inputs.EnableFaceNormal; // Vertex attributes are stored sequentially in vertex buffers. The attributes can include position, normal vector, and color. // All vertices within a vertex buffer must have the same format. Possible formats are enumerated by VertexFormatBits. // Vertex format also determines the type of rendering effect that can be used with the vertex buffer. In this sample, // the color is always encoded in the vertex attributes. bufferStorage.FormatBits = useNormals ? VertexFormatBits.PositionNormalColored : VertexFormatBits.PositionColored; // The format of the vertices determines the size of the vertex buffer. int vertexBufferSizeInFloats = (useNormals ? VertexPositionNormalColored.GetSizeInFloats() : VertexPositionColored.GetSizeInFloats()) * bufferStorage.VertexBufferCount; numVerticesInMeshesBefore.Add(0); bufferStorage.VertexBuffer = new VertexBuffer(vertexBufferSizeInFloats); bufferStorage.VertexBuffer.Map(vertexBufferSizeInFloats); int numMeshes = meshes.Count; if (useNormals) { // A VertexStream is used to write data into a VertexBuffer. VertexStreamPositionNormalColored vertexStream = bufferStorage.VertexBuffer.GetVertexStreamPositionNormalColored(); for (int i = 0; i < numMeshes; i++) { var meshInfo = meshes[i]; Mesh mesh = meshInfo.Mesh; foreach (XYZ vertex in mesh.Vertices) { vertexStream.AddVertex(new VertexPositionNormalColored(vertex + meshInfo.Offset, meshInfo.Normal, meshInfo.ColorWithTransparency)); } numVerticesInMeshesBefore.Add(numVerticesInMeshesBefore.Last() + mesh.Vertices.Count); } } else { // A VertexStream is used to write data into a VertexBuffer. VertexStreamPositionColored vertexStream = bufferStorage.VertexBuffer.GetVertexStreamPositionColored(); for (int i = 0; i < numMeshes; i++) { var meshInfo = meshes[i]; Mesh mesh = meshInfo.Mesh; // make the color of all faces white in HLR ColorWithTransparency color = meshInfo.ColorWithTransparency; foreach (XYZ vertex in mesh.Vertices) { vertexStream.AddVertex(new VertexPositionColored(vertex + meshInfo.Offset, color)); } numVerticesInMeshesBefore.Add(numVerticesInMeshesBefore.Last() + mesh.Vertices.Count); } } bufferStorage.VertexBuffer.Unmap(); // Primitives are specified using a pair of vertex and index buffers. An index buffer contains a sequence of indices into // the associated vertex buffer, each index referencing a particular vertex. int meshNumber = 0; bufferStorage.IndexBufferCount = bufferStorage.PrimitiveCount * IndexTriangle.GetSizeInShortInts(); int indexBufferSizeInShortInts = 1 * bufferStorage.IndexBufferCount; bufferStorage.IndexBuffer = new IndexBuffer(indexBufferSizeInShortInts); bufferStorage.IndexBuffer.Map(indexBufferSizeInShortInts); { // An IndexStream is used to write data into an IndexBuffer. IndexStreamTriangle indexStream = bufferStorage.IndexBuffer.GetIndexStreamTriangle(); foreach (MeshInfo meshInfo in meshes) { Mesh mesh = meshInfo.Mesh; int startIndex = numVerticesInMeshesBefore[meshNumber]; for (int i = 0; i < mesh.NumTriangles; i++) { MeshTriangle mt = mesh.get_Triangle(i); // Add three indices that define a triangle. indexStream.AddTriangle(new IndexTriangle((int)(startIndex + mt.get_Index(0)), (int)(startIndex + mt.get_Index(1)), (int)(startIndex + mt.get_Index(2)))); } meshNumber++; } } bufferStorage.IndexBuffer.Unmap(); // VertexFormat is a specification of the data that is associated with a vertex (e.g., position). bufferStorage.VertexFormat = new VertexFormat(bufferStorage.FormatBits); // Effect instance is a specification of the appearance of geometry. For example, it may be used to specify color, if there is no color information provided with the vertices. bufferStorage.EffectInstance = new EffectInstance(bufferStorage.FormatBits); }
private void CreateGround() { const int rows = 5; const int cols = 5; PointRGB[] vertices = new PointRGB[rows * cols]; double surfaceOffset = -3; Random random = new Random(); double maxHeightSurface = 3; double minHeightSurface = -3; int indexArray = 0; for (int j = 0; j < rows; j++) { for (int i = 0; i < cols; i++) { // values 87.5 and 50 for dividing in 4 parts the grid(350x200) double x = i * 87.5 - 150; double y = j * 50 - 100; double z = random.NextDouble() * (maxHeightSurface - minHeightSurface) + minHeightSurface; // sets saddlebrown color int red = 139; int green = 69; int blue = 19; if (x == -62.5 && y == 0 || x == 25 && y == 0) { z = -surfaceOffset; } if ((i % 2 == 0) && (j % 2 == 0)) { // sets greenforest color red = 34; green = 139; blue = 34; } vertices[indexArray++] = new PointRGB(x, y, z, (byte)red, (byte)green, (byte)blue); } } IndexTriangle[] triangles = new IndexTriangle[((rows - 1) * (cols - 1) * 2)]; indexArray = 0; for (int j = 0; j < (rows - 1); j++) { for (int i = 0; i < (cols - 1); i++) { triangles[indexArray++] = (new IndexTriangle(i + j * cols, i + j * cols + 1, i + (j + 1) * cols + 1)); triangles[indexArray++] = (new IndexTriangle(i + j * cols, i + (j + 1) * cols + 1, i + (j + 1) * cols)); } } Mesh surface = new Mesh(); surface.NormalAveragingMode = Mesh.normalAveragingType.Averaged; surface.Vertices = vertices; surface.Triangles = triangles; // sets surface lower than the grid surface.Translate(0, 0, surfaceOffset); model1.Entities.Add(surface); // fits the model in the model1 model1.ZoomFit(); }
/// <summary> /// Splits original Entity in three sections (red, blue, yellow) using direction vector. /// </summary> public void QuickSplit(Mesh originalEntity, Vector3D direction) { int redT = 0; int blueT = 0; int yellowT = 0; Mesh redSection = (Mesh)originalEntity.Clone(); Mesh blueSection = (Mesh)originalEntity.Clone(); Mesh yellowSection = (Mesh)originalEntity.Clone(); blueSection.Visible = true; redSection.Visible = true; yellowSection.Visible = true; int[] redPoints = new int[originalEntity.Vertices.Length]; int[] yellowPoints = new int[originalEntity.Vertices.Length]; int[] bluePoints = new int[originalEntity.Vertices.Length]; // gets graph of originalEntity's edges LinkedList <SharedEdge>[] sell; int res = Utility.GetEdgesWithoutDuplicates(originalEntity.Triangles, originalEntity.Vertices.Count(), out sell); //convert original IndexTriangles to MyIndexTriangle MyIndexTriangle[] originalT = new MyIndexTriangle[originalEntity.Triangles.Length]; for (int i = 0; i < originalEntity.Triangles.Length; i++) { originalT[i] = new MyIndexTriangle(originalEntity.Triangles[i].V1, originalEntity.Triangles[i].V2, originalEntity.Triangles[i].V3, false, 0, originalEntity.Vertices); } // gets a first list of triangles SplitTrianglesByNormal(originalEntity, direction, originalT, redSection, yellowSection, blueSection, redPoints, yellowPoints, bluePoints, ref redT, ref yellowT, ref blueT); // checks yellow triangles ReassingYellowTriangles(originalEntity, direction, originalT, sell, redSection, yellowSection, blueSection, redPoints, yellowPoints, bluePoints, ref redT, ref yellowT, ref blueT); // updates triangle section arrays IndexTriangle[] blue = new IndexTriangle[blueT]; IndexTriangle[] red = new IndexTriangle[redT]; IndexTriangle[] yellow = new IndexTriangle[yellowT]; int redDestCount = 0; int blueDestCount = 0; int yellowDestCount = 0; for (int i = 0; i < originalEntity.Triangles.Length; i++) { if (redSection.Triangles[i] != null) { red[redDestCount] = (IndexTriangle)redSection.Triangles[i].Clone(); redDestCount++; } if (blueSection.Triangles[i] != null) { blue[blueDestCount] = (IndexTriangle)blueSection.Triangles[i].Clone(); blueDestCount++; } if (yellowSection.Triangles[i] != null) { yellow[yellowDestCount] = (IndexTriangle)yellowSection.Triangles[i].Clone(); yellowDestCount++; } } redSection.Triangles = red; blueSection.Triangles = blue; yellowSection.Triangles = yellow; //Deletes and reorders Vertices lists yellowSection = DeleteUnusedVertices(yellowSection); redSection = DeleteUnusedVertices(redSection); blueSection = DeleteUnusedVertices(blueSection); SetBlockDefinition(blueSection, redSection, yellowSection); DrawNormalDirection(Point3D.Origin, originalEntity.BoxSize.Diagonal); _model1.Entities.Regen(); _model1.Invalidate(); }
public static void GenMap(int numberOfOtherCountries, int bigCountryThickness, double gridCellSize, ref GameObject[,] cells) { int MAP_WIDTH = cells.GetLength(0); int MAP_HEIGHT = cells.GetLength(1); // Grid corner vertices (with slight deform) Vector[,] gridPoints = new Vector[MAP_WIDTH + 1, MAP_HEIGHT + 1]; for (int x = 0; x < MAP_WIDTH + 1; x++) { for (int y = 0; y < MAP_HEIGHT + 1; y++) { gridPoints[x, y] = new Vector(-gridCellSize * (MAP_WIDTH / 2) + x * gridCellSize, gridCellSize * (MAP_HEIGHT / 2) - y * gridCellSize) + RandomGen.NextVector(gridCellSize / 5, gridCellSize / 3); } } IndexTriangle[] idxTriRect = new IndexTriangle[] { new IndexTriangle(0, 2, 1), new IndexTriangle(2, 0, 3) }; for (int x = 0; x < MAP_WIDTH; x++) { for (int y = 0; y < MAP_HEIGHT; y++) { Vector cellPosition = (gridPoints[x, y] + gridPoints[x, y + 1] + gridPoints[x + 1, y] + gridPoints[x + 1, y + 1]) / 4; var polyshape = new Polygon(new ShapeCache( new Vector[] { gridPoints[x, y] - cellPosition, gridPoints[x, y + 1] - cellPosition, gridPoints[x + 1, y + 1] - cellPosition, gridPoints[x + 1, y] - cellPosition }, // corners idxTriRect // triangles ), false); var cell = new GameObject(gridCellSize, gridCellSize, polyshape); cell.Position = cellPosition; //cell.Color = RandomGen.NextColor(); cells[x, y] = cell; } } int freeCellCnt = MAP_WIDTH * MAP_HEIGHT; // 1. Outside is USSR for (int x = 0; x < MAP_WIDTH; x++) { for (int y = 0; y < bigCountryThickness; y++) { cells[x, y].Color = USSR_COLOR; //TODO: Translucient //TODO: Set the contry to the tag cells[x, MAP_HEIGHT - 1 - y].Color = USSR_COLOR; //TODO: Translucient freeCellCnt -= 2; } } for (int y = bigCountryThickness; y < MAP_HEIGHT - bigCountryThickness; y++) { for (int x = 0; x < bigCountryThickness; x++) { cells[x, y].Color = USSR_COLOR; //TODO: Translucient //TODO: Set the contry to the tag cells[MAP_WIDTH - 1 - x, y].Color = USSR_COLOR; //TODO: Translucient freeCellCnt -= 2; } } // 2. You are at the center cells[MAP_WIDTH / 2, MAP_HEIGHT / 2].Color = YOURZISTAN; //TODO: Set tag to point to your country freeCellCnt--; // 3. Other countries are placed randomly for (int i = 0; i < numberOfOtherCountries; i++) { bool foundSpot = false; do { int x = RandomGen.NextInt(1, MAP_WIDTH - 2); int y = RandomGen.NextInt(1, MAP_HEIGHT - 2); if (cells[x, y].Color == Color.White) { freeCellCnt--; cells[x, y].Color = RandomGen.NextColor(); foundSpot = true; //TODO: Set tag to point to a country } } while (!foundSpot); } // Evolve bool foundWhite = false; do { foundWhite = false; List <Tuple <int, int, Color> > toFill = new List <Tuple <int, int, Color> >(); for (int x = 1; x < MAP_WIDTH - 1; x++) { for (int y = 1; y < MAP_HEIGHT - 1; y++) { // Free to fill if (cells[x, y].Color == Color.White) { foundWhite = true; List <Color> nearbyColors = new List <Color>(); for (int dx = -1; dx < 2; dx++) { Color neighbourColor = cells[x + dx, y].Color; if (neighbourColor != Color.White && (neighbourColor != USSR_COLOR || RandomGen.NextInt(10) == 1)) { nearbyColors.Add(neighbourColor); } } for (int dy = -1; dy < 2; dy++) { Color neighbourColor = cells[x, y + dy].Color; if (neighbourColor != Color.White && (neighbourColor != USSR_COLOR || RandomGen.NextInt(10) == 1)) { nearbyColors.Add(neighbourColor); } } if (nearbyColors.Count > 0) { Color mostOccuring = nearbyColors.GroupBy(i => i).OrderByDescending(grp => grp.Count()).Select(grp => grp.Key).First(); // Store into temp list so that for this round it is a level ground toFill.Add(new Tuple <int, int, Color>(x, y, mostOccuring)); } } } } foreach (var tf in toFill) { // Little bit of stochasticity if (RandomGen.NextInt(5) < 4) { cells[tf.Item1, tf.Item2].Color = tf.Item3; freeCellCnt--; } } } while (foundWhite); }
// Gets the list of the vertices of the triangle Point3D[] GetTriangleVertices(IndexTriangle tri) { return(new Point3D[] { Vertices[tri.V1], Vertices[tri.V2], Vertices[tri.V3] }); }