public GroundMaterial(SquareCell caller) { if (decays) { CallCountDown(caller); } }
public SquareCell getSquare() { List <SquareCell> squares = new List <SquareCell>(); foreach (SquareCell topCell in topCells) { if (!topCell.busy) { squares.AddRange(topCell.getSquares()); } } if (squares.Count == 0) { throw new Exception("No more available square"); // Screen is full } squares = squares.OrderBy(i => i.side) .ThenBy(i => i.center.x) .ThenBy(i => i.center.y) .ToList(); SquareCell choice = squares[UnityEngine.Random.Range(0, squares.Count)]; choice.setBusy(); //Debug.Log("Side: "+ choice.side + ", center: " + choice.center + ", num choices: " + squares.Count); return(choice); }
void FillHole(SquareCell cell, Vector3 v1) { SquareCell eastNeighbor = cell.GetNeighbor(SquareDirection.E); SquareCell northNeighbor = cell.GetNeighbor(SquareDirection.N); SquareCell northEastNeighbor = null; if (northNeighbor == null || eastNeighbor == null) { return; } northEastNeighbor = cell.GetNeighbor(SquareDirection.N).GetNeighbor(SquareDirection.E); Vector3 bridgeN = SquareMetrics.GetBridge(SquareDirection.N); Vector3 n = v1 + bridgeN; Vector3 bridgeE = SquareMetrics.GetBridge(SquareDirection.E); Vector3 e = v1 + bridgeE; Vector3 ne = v1 + bridgeN + bridgeE; Color northColor, eastColor, northEastColor; northColor = eastColor = northEastColor = cell.Color; if (northNeighbor != null) { n.y = northNeighbor.transform.localPosition.y; northColor = northNeighbor.Color; } if (eastNeighbor != null) { e.y = eastNeighbor.transform.localPosition.y; eastColor = eastNeighbor.Color; } if (northEastNeighbor != null) { ne.y = northEastNeighbor.transform.localPosition.y; northEastColor = northEastNeighbor.Color; } Vector3 center = v1 + 0.5f * (bridgeN + bridgeE); center.y = (Mathf.Max(v1.y, e.y, n.y, ne.y) + Mathf.Min(v1.y, e.y, n.y, ne.y)) / 2f; Color blendColor = GetBlendColor(cell.Color, northColor, eastColor, northEastColor); // Triangle vertices should be clockwise // First Triangle to add will be v1, n, center AddTriangle(v1, n, center); AddTriangleColor(cell.Color, northColor, blendColor); // Second will be v1, center, e AddTriangle(v1, center, e); AddTriangleColor(cell.Color, blendColor, eastColor); // Third will be n, ne, center AddTriangle(n, ne, center); AddTriangleColor(northColor, northEastColor, blendColor); // Last is ne, e, center AddTriangle(ne, e, center); AddTriangleColor(northEastColor, eastColor, blendColor); }
private SquareCell[,] ProcessSquare(int[,] matrix) { var processed = new SquareCell[matrix.GetLength(0), matrix.GetLength(0)]; for (var r = matrix.GetLength(0) - 1; r >= 0; r--) { for (var c = matrix.GetLength(0) - 1; c >= 0; c--) { var rightZeros = 0; var belowZeros = 0; if (matrix[r, c] == 0) { rightZeros++; belowZeros++; if (c + 1 < matrix.GetLength(0)) { var previous = processed[r, c + 1]; rightZeros += previous.ZerosRight; } if (r + 1 < matrix.GetLength(0)) { var previous = processed[r + 1, c]; belowZeros += previous.ZerosBelow; } } processed[r, c] = new SquareCell(rightZeros, belowZeros); } } return(processed); }
// 对比open中F最小 private SquareCell GetMinF() { if (open.Count == 0) { Debug.Log("死路一条,走不了"); } for (int i = 0; i < open.Count; i++) { open[i].H = (dester.Line - open[i].Line) + (dester.Column - open[i].Column); open[i].F = open[i].G + open[i].H; } for (int i = 0; i < open.Count; i++) { for (int j = i + 1; j < open.Count; j++) { if (open[i].F >= open[j].F) { SquareCell temp = open[i]; open[i] = open[j]; open[j] = temp; } } } //Debug.Log(open.Count); return(open[0]); }
public void Init() { Debug.Log("+++++++++"); grig = SquareGrig.Instantiate; cells = grig.cells; player = grig.player; dester = grig.dester; close.Add(player); now = player; while (true) { if (over == true) { break; } if (open.Count != 0) { close.AddRange(open.ToArray()); open.Clear(); } Debug.Log(now.Line + "---" + now.Column); Sides(now); now.gameObject.GetComponent <Image>().color = Color.green; } }
void TriangulateRoadCentre(SquareCell cell, Vector3 centre, Vector3 vs0, Vector3 vs1, Vector3 vs2, Vector3 vs3) { roads.AddTriangle(centre, vs0, GetMidVector(vs0, vs1)); roads.AddTriangle(centre, GetMidVector(vs0, vs1), vs1); roads.AddTriangle(centre, vs1, GetMidVector(vs1, vs2)); roads.AddTriangle(centre, GetMidVector(vs1, vs2), vs2); roads.AddTriangle(centre, vs2, GetMidVector(vs2, vs3)); roads.AddTriangle(centre, GetMidVector(vs2, vs3), vs3); roads.AddTriangle(centre, vs3, GetMidVector(vs3, vs0)); roads.AddTriangle(centre, GetMidVector(vs3, vs0), vs0); // W float midU = cell.HasRoadThroughEdge(GridDirection.W) ? 1f : 0f; roads.AddTriangleUV(new Vector2(1f, 1f), new Vector2(0f, 1f), new Vector2(midU, 1f)); roads.AddTriangleUV(new Vector2(1f, 1f), new Vector2(midU, 1f), new Vector2(0f, 1f)); // N midU = cell.HasRoadThroughEdge(GridDirection.N) ? 1f : 0f; roads.AddTriangleUV(new Vector2(1f, 1f), new Vector2(0f, 1f), new Vector2(midU, 1f)); roads.AddTriangleUV(new Vector2(1f, 1f), new Vector2(midU, 1f), new Vector2(0f, 1f)); // E midU = cell.HasRoadThroughEdge(GridDirection.E) ? 1f : 0f; roads.AddTriangleUV(new Vector2(1f, 1f), new Vector2(0f, 1f), new Vector2(midU, 1f)); roads.AddTriangleUV(new Vector2(1f, 1f), new Vector2(midU, 1f), new Vector2(0f, 1f)); // S midU = cell.HasRoadThroughEdge(GridDirection.S) ? 1f : 0f; roads.AddTriangleUV(new Vector2(1f, 1f), new Vector2(0f, 1f), new Vector2(midU, 1f)); roads.AddTriangleUV(new Vector2(1f, 1f), new Vector2(midU, 1f), new Vector2(0f, 1f)); }
void AddCliffEdges(SquareCell cell) { AddCliffEdge(cell, GridDirection.N); AddCliffEdge(cell, GridDirection.E); AddCliffEdge(cell, GridDirection.S); AddCliffEdge(cell, GridDirection.W); }
void Mine(SquareCell cell) { if (cell.block.Type is BS_Solid) { NotificationExtensions.PostNotification(this, JobMetrics.MINING_JOB_POST_NOTICE, cell.block); } }
//This method trigger the creation of the objects on which films are rendered void spawnFilms(RectTransform canvasRect, VideoClip[] clips) { GameObject films = new GameObject(); films.name = "Films"; films.transform.SetParent(canvasRect.transform); float available_size = (1 - (clips.Length + 1) * 0.01f) * Mathf.Min(canvasRect.rect.width, canvasRect.rect.height); float min_width = canvasRect.rect.width / 8f * Mathf.Max(15f / (5 + 1f), 1f); float max_width = canvasRect.rect.width / 7.5f * Mathf.Max(15f / (5 + 1f), 1f); SquaresTree sqt = new SquaresTree(canvasRect.rect.width * widthRatio, canvasRect.rect.height, max_width, min_width, canvasRect.position - new Vector3(canvasRect.rect.width * (1 - widthRatio) * 0.5f, 0, 0)); int choice = Random.Range(0, clips.Length); SquareCell sqc = sqt.getSquare(); float size = sqc.side; GameObject vid = Instantiate(image, sqc.center, Quaternion.identity); vid.name = string.Format("film{0}", 1); vid.transform.SetParent(films.transform); var videoPlayer = vid.AddComponent <UnityEngine.Video.VideoPlayer>(); videoPlayer.clip = clips[choice]; videoPlayer.playOnAwake = false; (vid.GetComponent <VideoController>()).StartCoroutine((vid.GetComponent <VideoController>()).SetUpFilm()); (vid.GetComponent <VideoController>()).SetSize(size, size); (vid.GetComponent <VideoController>()).SetPos(sqc.center); }
/// Linearly interpolate the position where an isosurface cuts /// an edge between two vertices, each with their own scalar value /// Vector2 VertexInterp(float isolevel, ref SquareCell cell, int pid1, int pid2) { Vector2 p1 = cell.p[pid1]; Vector2 p2 = cell.p[pid2]; float valp1 = cell.val[pid1]; float valp2 = cell.val[pid2]; float mu; Vector2 p = Vector2.zero; if (Math.Abs(isolevel - valp1) < 0.00001) { return(p1); } if (Math.Abs(isolevel - valp2) < 0.00001) { return(p2); } if (Math.Abs(valp1 - valp2) < 0.00001) { return(p1); } mu = (isolevel - valp1) / (valp2 - valp1); p.x = p1.x + mu * (p2.x - p1.x); p.y = p1.y + mu * (p2.y - p1.y); return(p); }
public void SetOutgoingRiver(GridDirection direction) { if (hasOutgoingRivers[(int)direction] || HasRoads) { Debug.Log("Could not add river"); return; } SquareCell neighbor = GetNeighbor(direction); if (!neighbor || CentreElevation < neighbor.CentreElevation) { Debug.Log("Could not add river uphill"); return; } if (hasIncomingRivers[(int)direction]) { RemoveIncomingRiver(direction); } hasOutgoingRivers[(int)direction] = true; RefreshChunkOnly(); neighbor.RemoveOutgoingRiver(direction.Opposite()); neighbor.hasIncomingRivers[(int)direction.Opposite()] = true; neighbor.RefreshChunkOnly(); }
void Triangulate(SquareCell cell) { for (SquareDirection d = SquareDirection.N; d < SquareDirection.NW; d++) { // Debug.Log("Triangulating direction " + d.ToString()); Triangulate(d, cell); d++; } }
IEnumerator CallCountDown(SquareCell caller) { //Debug.Log("callCountDown Called"); yield return(new WaitForSeconds(lifetime)); SetToPrevious(caller); caller.Refresh(); //Debug.Log("mud revereted to previous"); }
// 检查周边是否可加入open private void Sides(SquareCell squareCell) { if (CreateZIsTrue(squareCell.Line - 1, squareCell.Column) != true & cellIsIf(squareCell.Line - 1, squareCell.Column) != true) { squareCell.IsIf = true; squareCell.G = 10; open.Add(GetCell(squareCell.Line - 1, squareCell.Column)); } if (CreateZIsTrue(squareCell.Line - 1, squareCell.Column + 1) != true & cellIsIf(squareCell.Line - 1, squareCell.Column + 1) != true) { squareCell.IsIf = true; squareCell.G = 14; open.Add(GetCell(squareCell.Line - 1, squareCell.Column + 1)); } if (CreateZIsTrue(squareCell.Line - 1, squareCell.Column - 1) != true & cellIsIf(squareCell.Line - 1, squareCell.Column - 1) != true) { squareCell.IsIf = true; squareCell.G = 14; open.Add(GetCell(squareCell.Line - 1, squareCell.Column - 1)); } if (CreateZIsTrue(squareCell.Line, squareCell.Column + 1) != true & cellIsIf(squareCell.Line, squareCell.Column + 1) != true) { squareCell.IsIf = true; squareCell.G = 10; open.Add(GetCell(squareCell.Line, squareCell.Column + 1)); } if (CreateZIsTrue(squareCell.Line, squareCell.Column - 1) != true & cellIsIf(squareCell.Line, squareCell.Column - 1) != true) { squareCell.IsIf = true; squareCell.G = 10; open.Add(GetCell(squareCell.Line, squareCell.Column - 1)); } if (CreateZIsTrue(squareCell.Line + 1, squareCell.Column) != true & cellIsIf(squareCell.Line + 1, squareCell.Column) != true) { squareCell.IsIf = true; squareCell.G = 10; open.Add(GetCell(squareCell.Line + 1, squareCell.Column)); } if (CreateZIsTrue(squareCell.Line + 1, squareCell.Column + 1) != true & cellIsIf(squareCell.Line + 1, squareCell.Column + 1) != true) { squareCell.IsIf = true; squareCell.G = 14; open.Add(GetCell(squareCell.Line + 1, squareCell.Column + 1)); } if (CreateZIsTrue(squareCell.Line + 1, squareCell.Column - 1) != true & cellIsIf(squareCell.Line + 1, squareCell.Column - 1) != true) { squareCell.IsIf = true; squareCell.G = 14; open.Add(GetCell(squareCell.Line + 1, squareCell.Column - 1)); } if (over != true) { now = GetMinF(); } }
public void ConnectWithNeigbour(SquareCell neighbour, GridDirection direction) { //if (parentCell.GetVertexElevations.AverageElevation == neighbour.GetVertexElevations.AverageElevation) //{ ConnectNodes(GetNode(NodeDirection.In, direction), neighbour.roadNetwork.GetNode(NodeDirection.Out, direction.Opposite())); ConnectNodes(GetNode(NodeDirection.Out, direction), neighbour.roadNetwork.GetNode(NodeDirection.In, direction.Opposite())); network.DeleteLink(GetNode(NodeDirection.Out, direction), GetNode(NodeDirection.In, direction)); network.DeleteLink(neighbour.roadNetwork.GetNode(NodeDirection.Out, direction.Opposite()), neighbour.roadNetwork.GetNode(NodeDirection.In, direction.Opposite())); //} }
void AddCellToChunk(int x, int z, SquareCell cell) { int chunkX = x / GridMetrics.chunkSizeX; int chunkZ = z / GridMetrics.chunkSizeZ; SquareGridChunk chunk = chunks[chunkX + chunkZ * chunkCountX]; int localX = x - chunkX * GridMetrics.chunkSizeX; int localZ = z - chunkZ * GridMetrics.chunkSizeZ; chunk.AddCell(localX + localZ * GridMetrics.chunkSizeX, cell); }
void ActOnCell(SquareCell cell) { if (handlerState == IHState.Inspect) { Inspect(cell); } else if (handlerState == IHState.Mine) { Mine(cell); } }
public override void SetNeighbor(SquareDirection direction, SquareCell cell) { if (cell == null) { neighbors[(int)direction] = null; } else { neighbors[(int)direction] = cell; cell.neighbors[(int)direction.Opposite()] = this; } }
void EditCells(SquareCell cell, Vector3 hitpoint) { for (int x = 0; x < pointerSize; x++) { for (int z = 0; z < pointerSize; z++) { Vector3 offPos = new Vector3(cell.coordinates.X + x, 0, cell.coordinates.Z + z); SquareCell offCell = squareGrid.GetCell(offPos); EditCell(offCell, hitpoint); } } }
// Function to instantiate the cell at the given position void CreateCell(int x, int y, int i) { Vector3 position; position.x = x * 1.25f; position.y = y * 1.25f; position.z = 0; SquareCell cell = cells[i] = Instantiate(cellPrefab); cell.transform.SetParent(transform, false); cell.transform.localPosition = position; }
public void SetToPrevious(SquareCell caller) { tileTypeName = previousMaterial.tileTypeName; color = previousMaterial.color; blendEdge = previousMaterial.blendEdge; decays = previousMaterial.decays; lifetime = previousMaterial.lifetime; previousMaterial = previousMaterial.previousMaterial; if (decays) { CallCountDown(caller); } }
void CreateCell(int x, int z, int i, Block block) { SquareCell cell = cells[i] = Instantiate(cellPrefab); cell.point = block.Point; cell.block = block; cell.RefreshPosition(); blocksToCellsMap.Add(block, cell); AddCellToChunk(x, z, cell); }
public void AddRoad() { SquareCell randomRoad = townRoads[Random.Range(0, townRoads.Count)]; GridDirection randomDirection = (GridDirection)(Random.Range(0, 3) * 2); SquareCell randomNeighbour = randomRoad.GetNeighbor(randomDirection); if (randomNeighbour && randomNeighbour.UrbanLevel == 0 && !townRoads.Contains(randomNeighbour)) { randomRoad.AddRoad(randomDirection); randomNeighbour.AddRoad(randomDirection.Opposite()); townRoads.Add(randomNeighbour); } }
void MoveEditorPointer(SquareCell cell, GridDirection vertex) { if (activeMode == EditMode.color || activeMode == EditMode.rivers || activeMode == EditMode.roads || activeMode == EditMode.water_level || activeMode == EditMode.building || activeMode == EditMode.trees || activeMode == EditMode.rocks || activeMode == EditMode.mast || activeMode == EditMode.lighthouse || activeMode == EditMode.industry || activeMode == EditMode.town) { pointerLocation = GridCoordinates.ToPosition(cell.coordinates) + Vector3.up * cell.CentreElevation * GridMetrics.elevationStep; } if (activeMode == EditMode.elevation) { pointerLocation = GridCoordinates.ToPosition(cell.coordinates) + GridMetrics.GetEdge(vertex) + Vector3.up * (int)cell.GridElevations[vertex] * GridMetrics.elevationStep; } }
void AdjustVerticleHeight() { if (mainCamera.orthographic) { transform.position = new Vector3(transform.position.x, 0, transform.position.z); } else { SquareCell cell = grid.GetCell(transform.position); Vector3 target = new Vector3(transform.position.x, 0, transform.position.z) + Vector3.up * cell.GetMaxElevation() * GridMetrics.elevationStep; transform.position = Vector3.SmoothDamp(transform.position, target, ref velocity, smoothTime); } }
public void RemoveIncomingRiver(GridDirection direction) { if (!hasIncomingRivers[(int)direction]) { return; } hasIncomingRivers[(int)direction] = false; RefreshChunkOnly(); SquareCell neighbor = GetNeighbor(direction); hasOutgoingRivers[(int)direction.Opposite()] = false; neighbor.RefreshChunkOnly(); }
void AddWaterForSquare(SquareCell cell, Vector3 centre) { centre.y = cell.WaterSurfaceY; Vector3 c0 = centre + GridMetrics.GetEdge(GridDirection.SW); Vector3 c1 = centre + GridMetrics.GetEdge(GridDirection.NW); Vector3 c2 = centre + GridMetrics.GetEdge(GridDirection.NE); Vector3 c3 = centre + GridMetrics.GetEdge(GridDirection.SE); if (cell.IsFullyUnderwater) { water.AddQuad(c0, c1, c2, c3); } else if (cell.IsPartUnderwater) { float v0 = 0f, v1 = 0f, v2 = 0f, v3 = 0f; if (cell.GetNeighbor(GridDirection.N) && !cell.GetNeighbor(GridDirection.N).IsUnderwater) { v1 = 1f; v2 = 1f; } if (cell.GetNeighbor(GridDirection.NE) && !cell.GetNeighbor(GridDirection.NE).IsUnderwater) { v2 = 1f; } if (cell.GetNeighbor(GridDirection.E) && !cell.GetNeighbor(GridDirection.E).IsUnderwater) { v2 = 1f; v3 = 1f; } if (cell.GetNeighbor(GridDirection.SE) && !cell.GetNeighbor(GridDirection.SE).IsUnderwater) { v3 = 1f; } if (cell.GetNeighbor(GridDirection.S) && !cell.GetNeighbor(GridDirection.S).IsUnderwater) { v3 = 1f; v0 = 1f; } if (cell.GetNeighbor(GridDirection.SW) && !cell.GetNeighbor(GridDirection.SW).IsUnderwater) { v0 = 1f; } if (cell.GetNeighbor(GridDirection.W) && !cell.GetNeighbor(GridDirection.W).IsUnderwater) { v0 = 1f; v1 = 1f; } if (cell.GetNeighbor(GridDirection.NW) && !cell.GetNeighbor(GridDirection.NW).IsUnderwater) { v1 = 1f; } waterShore.AddQuad(c0, c1, c2, c3); waterShore.AddQuadV(v0, v1, v2, v3); } }
public bool HasCliff(GridDirection direction) { SquareCell neighbor = GetNeighbor(direction); if (neighbor) { bool noCliff = (int)vertexElevations[direction.Previous()] == (int)neighbor.vertexElevations[direction.Opposite().Next()] && (int)vertexElevations[direction.Next()] == (int)neighbor.vertexElevations[direction.Opposite().Previous()]; return(!noCliff); } else { return(false); } }
void spawnImage(Texture2D texture) { if (sqt.CountSquare() != 0) { SquareCell sqc = sqt.getSquare(); float size = sqc.side; GameObject img = Instantiate(image, sqc.center, Quaternion.identity); img.name = string.Format("image{0}", counter); img.transform.SetParent(images.transform); (img.GetComponent <ImageController>()).StartCoroutine((img.GetComponent <ImageController>()).SetUpImage(texture, sqc)); (img.GetComponent <ImageController>()).SetSize(size, size); (img.GetComponent <ImageController>()).SetPos(sqc.center); } }
/// this method renders two meshes: /// cmesh the collision mesh (just the outline vertices extruded) /// rmesh the render mesh (the 2d surface of the given voxel lattices) /// public void MarchSquares(out Mesh cmesh, out Mesh rmesh, ref SquareCell[,] cells, float isolevel) { Vector2 uvScale = new Vector2(1.0f / cells.GetLength(0), 1.0f / cells.GetLength(1)); // triangle index counter int tricount = 0; // collider triangle index counter int ctricount = 0; // mesh data arrays - just clear when reused if (vert == null) vert = new ArrayList(); else vert.Clear(); if (uv == null) uv = new ArrayList(); else uv.Clear(); if (tri == null) tri = new ArrayList(); else tri.Clear(); if (norm == null) norm = new ArrayList(); else norm.Clear(); // collider mesh arrays if (cvert == null) cvert = new ArrayList(); else cvert.Clear(); if (cuv == null) cuv = new ArrayList(); else cuv.Clear(); if (ctri == null) ctri = new ArrayList(); else ctri.Clear(); if (cnorm == null) cnorm = new ArrayList(); else cnorm.Clear(); for (int i = 0; i < cells.GetLength(0); i++) { for (int j = 0; j < cells.GetLength(1); j++) { SquareCell cell = cells[i,j]; Triangle[] triangles; Polygonise(cell, out triangles, isolevel); for (int k = 0; k < triangles.Length; k++) { Triangle triangle = triangles[k]; if (triangle != null) { Vector3 p0 = new Vector3(triangle.p[0].x, 0, triangle.p[0].y); Vector3 p1 = new Vector3(triangle.p[1].x, 0, triangle.p[1].y); Vector3 p2 = new Vector3(triangle.p[2].x, 0, triangle.p[2].y); /// Start Vertices One --------------------------------------- vert.Add(p0); vert.Add(p1); vert.Add(p2); // Triangles tri.Add(tricount); tri.Add(tricount+1); tri.Add(tricount+2); // Normals Vector3 vn1 = p0 - p1; Vector3 vn2 = p0 - p2; Vector3 n = Vector3.Normalize ( Vector3.Cross(vn1,vn2) ); norm.Add(n); norm.Add(n); norm.Add(n); uv.Add(Vector2.Scale(new Vector2 (p0.x, p0.z), new Vector2(uvScale.x, uvScale.y))); uv.Add(Vector2.Scale(new Vector2 (p1.x, p1.z), new Vector2(uvScale.x, uvScale.y))); uv.Add(Vector2.Scale(new Vector2 (p2.x, p2.z), new Vector2(uvScale.x, uvScale.y))); tricount += 3; /// END Vertices One --------------------------------------- if (triangle.outerline[0] != -1) { Vector3 o1 = new Vector3(triangle.p[triangle.outerline[0]].x, 0, triangle.p[triangle.outerline[0]].y); Vector3 o2 = new Vector3(triangle.p[triangle.outerline[1]].x, 0, triangle.p[triangle.outerline[1]].y); Vector3 bo1 = o1; o1.y = -1; // o1 transposed one unit down Vector3 bo2 = o2; o2.y = -1; // o2 transposed one unit down /// Start Vertices Two --------------------------------------- cvert.Add(o1); cvert.Add(o2); cvert.Add(bo1); // Triangles ctri.Add(ctricount); ctri.Add(ctricount+1); ctri.Add(ctricount+2); // Normals Vector3 ovn1 = o1 - o2; Vector3 ovn2 = o1 - bo1; Vector3 on = Vector3.Normalize ( Vector3.Cross(ovn1,ovn2) ); cnorm.Add(on); cnorm.Add(on); cnorm.Add(on); cuv.Add(Vector2.zero); cuv.Add(Vector2.zero); cuv.Add(Vector2.zero); ctricount += 3; /// END Vertices Two --------------------------------------- /// Start Vertices Three --------------------------------------- cvert.Add(bo2); cvert.Add(bo1); cvert.Add(o2); // Triangles ctri.Add(ctricount); ctri.Add(ctricount+1); ctri.Add(ctricount+2); // Normals Vector3 oovn1 = o2 - bo1; Vector3 oovn2 = o2 - bo2; Vector3 oon = Vector3.Normalize ( Vector3.Cross(oovn1,oovn2) )*-1; cnorm.Add(oon); cnorm.Add(oon); cnorm.Add(oon); cuv.Add(Vector2.zero); cuv.Add(Vector2.zero); cuv.Add(Vector2.zero); ctricount += 3; /// END Vertices Three --------------------------------------- } } } } } // prepare the collision mesh cmesh = new Mesh(); cmesh.vertices = (Vector3[]) cvert.ToArray(typeof(Vector3)); cmesh.uv = (Vector2[]) cuv.ToArray(typeof(Vector2)); cmesh.triangles = (int[]) ctri.ToArray(typeof(int)); cmesh.normals = (Vector3[]) cnorm.ToArray(typeof(Vector3)); // prepare the render mesh rmesh = new Mesh(); rmesh.vertices = (Vector3[]) vert.ToArray(typeof(Vector3)); rmesh.uv = (Vector2[]) uv.ToArray(typeof(Vector2)); rmesh.triangles = (int[]) tri.ToArray(typeof(int)); rmesh.normals = (Vector3[]) norm.ToArray(typeof(Vector3)); }
/// Linearly interpolate the position where an isosurface cuts /// an edge between two vertices, each with their own scalar value /// Vector2 VertexInterp(float isolevel, ref SquareCell cell, int pid1, int pid2) { Vector2 p1 = cell.p[pid1]; Vector2 p2 = cell.p[pid2]; float valp1 = cell.val[pid1]; float valp2 = cell.val[pid2]; float mu; Vector2 p = Vector2.zero; if (Math.Abs(isolevel-valp1) < 0.00001) return(p1); if (Math.Abs(isolevel-valp2) < 0.00001) return(p2); if (Math.Abs(valp1-valp2) < 0.00001) return(p1); mu = (isolevel - valp1) / (valp2 - valp1); p.x = p1.x + mu * (p2.x - p1.x); p.y = p1.y + mu * (p2.y - p1.y); return(p); }
/// All cases /// /// Case 0 Case 1 Case 2 Case 3 Case 4 Case 5 Case 6 Case 7 /// O-----O O-----O O-----O O-----O O-----# O-----# O-----# O-----# /// | | | | | | | | | \| | \| | | | |/ | /// | | |\ | | /| |-----| | | |\ | | | | | | /// O-----O #-----O O-----# #-----# O-----O #-----O O-----# #-----# /// /// Case 8 Case 9 Case 10 Case 11 Case 12 Case 13 Case 14 Case 15 /// #-----O #-----O #-----O #-----O #-----# #-----# #-----# #-----# /// |/ | | | | |/ | | \| |-----| | | | | | | /// | | | | | | /| | | | | | /| |\ | | | /// O-----O #-----O O-----# #-----# O-----O #-----O O-----# #-----# /// private int Polygonise(SquareCell cell, out Triangle[] triangles, float isoLevel) { triangles = new Triangle[3]; // => Max 3 Triangles needed // decide which case we have // bool case_0 = cell.val[0] < isoLevel && cell.val[1] < isoLevel && cell.val[2] < isoLevel && cell.val[3] < isoLevel; bool case_1 = cell.val[0] >= isoLevel && cell.val[1] < isoLevel && cell.val[2] < isoLevel && cell.val[3] < isoLevel; bool case_2 = cell.val[0] < isoLevel && cell.val[1] >= isoLevel && cell.val[2] < isoLevel && cell.val[3] < isoLevel; bool case_3 = cell.val[0] >= isoLevel && cell.val[1] >= isoLevel && cell.val[2] < isoLevel && cell.val[3] < isoLevel; bool case_4 = cell.val[0] < isoLevel && cell.val[1] < isoLevel && cell.val[2] < isoLevel && cell.val[3] >= isoLevel; bool case_5 = cell.val[0] >= isoLevel && cell.val[1] < isoLevel && cell.val[2] < isoLevel && cell.val[3] >= isoLevel; bool case_6 = cell.val[0] < isoLevel && cell.val[1] >= isoLevel && cell.val[2] < isoLevel && cell.val[3] >= isoLevel; bool case_7 = cell.val[0] >= isoLevel && cell.val[1] >= isoLevel && cell.val[2] < isoLevel && cell.val[3] >= isoLevel; bool case_8 = cell.val[0] < isoLevel && cell.val[1] < isoLevel && cell.val[2] >= isoLevel && cell.val[3] < isoLevel; bool case_9 = cell.val[0] >= isoLevel && cell.val[1] < isoLevel && cell.val[2] >= isoLevel && cell.val[3] < isoLevel; bool case_10 = cell.val[0] < isoLevel && cell.val[1] >= isoLevel && cell.val[2] >= isoLevel && cell.val[3] < isoLevel; bool case_11 = cell.val[0] >= isoLevel && cell.val[1] >= isoLevel && cell.val[2] >= isoLevel && cell.val[3] < isoLevel; bool case_12 = cell.val[0] < isoLevel && cell.val[1] < isoLevel && cell.val[2] >= isoLevel && cell.val[3] >= isoLevel; bool case_13 = cell.val[0] >= isoLevel && cell.val[1] < isoLevel && cell.val[2] >= isoLevel && cell.val[3] >= isoLevel; bool case_14 = cell.val[0] < isoLevel && cell.val[1] >= isoLevel && cell.val[2] >= isoLevel && cell.val[3] >= isoLevel; bool case_15 = cell.val[0] >= isoLevel && cell.val[1] >= isoLevel && cell.val[2] >= isoLevel && cell.val[3] >= isoLevel; // make triangles int ntriang = 0; if (case_1) { triangles[0] = new Triangle(); triangles[0].p[0] = VertexInterp(isoLevel, ref cell, 2, 0); triangles[0].p[1] = VertexInterp(isoLevel, ref cell, 0, 1); triangles[0].p[2] = cell.p[0]; triangles[0].outerline[0] = 0; triangles[0].outerline[1] = 1; ntriang++; } if (case_2) { triangles[0] = new Triangle(); triangles[0].p[0] = VertexInterp(isoLevel, ref cell, 0, 1); triangles[0].p[1] = VertexInterp(isoLevel, ref cell, 1, 3); triangles[0].p[2] = cell.p[1]; triangles[0].outerline[0] = 0; triangles[0].outerline[1] = 1; ntriang++; } if (case_3) { triangles[0] = new Triangle(); triangles[0].p[0] = VertexInterp(isoLevel, ref cell, 0, 2); triangles[0].p[1] = cell.p[1]; triangles[0].p[2] = cell.p[0]; // no outer line... ntriang++; triangles[1] = new Triangle(); triangles[1].p[0] = VertexInterp(isoLevel, ref cell, 0, 2); triangles[1].p[1] = VertexInterp(isoLevel, ref cell, 1, 3); triangles[1].p[2] = cell.p[1]; triangles[1].outerline[0] = 0; triangles[1].outerline[1] = 1; ntriang++; } if (case_4) { triangles[0] = new Triangle(); triangles[0].p[0] = VertexInterp(isoLevel, ref cell, 1, 3); triangles[0].p[1] = VertexInterp(isoLevel, ref cell, 2, 3); triangles[0].p[2] = cell.p[3]; triangles[0].outerline[0] = 0; triangles[0].outerline[1] = 1; ntriang++; } if (case_5) { triangles[0] = new Triangle(); triangles[0].p[0] = VertexInterp(isoLevel, ref cell, 1, 3); triangles[0].p[1] = VertexInterp(isoLevel, ref cell, 2, 3); triangles[0].p[2] = cell.p[3]; triangles[0].outerline[0] = 0; triangles[0].outerline[1] = 1; ntriang++; triangles[1] = new Triangle(); triangles[1].p[0] = cell.p[0]; triangles[1].p[1] = VertexInterp(isoLevel, ref cell, 0, 2); triangles[1].p[2] = VertexInterp(isoLevel, ref cell, 0, 1); triangles[1].outerline[0] = 1; triangles[1].outerline[1] = 2; ntriang++; } if (case_6) { triangles[0] = new Triangle(); triangles[0].p[0] = VertexInterp(isoLevel, ref cell, 2, 3); triangles[0].p[1] = cell.p[3]; triangles[0].p[2] = cell.p[1]; // no outer line... ntriang++; triangles[1] = new Triangle(); triangles[1].p[0] = VertexInterp(isoLevel, ref cell, 0, 1); triangles[1].p[1] = VertexInterp(isoLevel, ref cell, 2, 3); triangles[1].p[2] = cell.p[1]; triangles[1].outerline[0] = 0; triangles[1].outerline[1] = 1; ntriang++; } if (case_7) { triangles[0] = new Triangle(); triangles[0].p[0] = VertexInterp(isoLevel, ref cell, 2, 3); triangles[0].p[1] = cell.p[3]; triangles[0].p[2] = cell.p[1]; // no outer line... ntriang++; triangles[1] = new Triangle(); triangles[1].p[0] = VertexInterp(isoLevel, ref cell, 0, 2); triangles[1].p[1] = VertexInterp(isoLevel, ref cell, 2, 3); triangles[1].p[2] = cell.p[1]; triangles[1].outerline[0] = 0; triangles[1].outerline[1] = 1; ntriang++; triangles[2] = new Triangle(); triangles[2].p[0] = cell.p[0]; triangles[2].p[1] = VertexInterp(isoLevel, ref cell, 0, 2); triangles[2].p[2] = cell.p[1]; // no outer line... ntriang++; } if (case_8) { triangles[0] = new Triangle(); triangles[0].p[0] = VertexInterp(isoLevel, ref cell, 2, 3); triangles[0].p[1] = VertexInterp(isoLevel, ref cell, 0, 2); triangles[0].p[2] = cell.p[2]; triangles[0].outerline[0] = 0; triangles[0].outerline[1] = 1; ntriang++; } if (case_9) { triangles[0] = new Triangle(); triangles[0].p[0] = cell.p[0]; triangles[0].p[1] = cell.p[2]; triangles[0].p[2] = VertexInterp(isoLevel, ref cell, 0, 1); // no outer line... ntriang++; triangles[1] = new Triangle(); triangles[1].p[0] = cell.p[2]; triangles[1].p[1] = VertexInterp(isoLevel, ref cell, 2, 3); triangles[1].p[2] = VertexInterp(isoLevel, ref cell, 0, 1); triangles[1].outerline[0] = 1; triangles[1].outerline[1] = 2; ntriang++; } if (case_10) { triangles[0] = new Triangle(); triangles[0].p[0] = cell.p[2]; triangles[0].p[1] = VertexInterp(isoLevel, ref cell, 2, 3); triangles[0].p[2] = VertexInterp(isoLevel, ref cell, 0, 2); triangles[0].outerline[0] = 1; triangles[0].outerline[1] = 2; ntriang++; triangles[1] = new Triangle(); triangles[1].p[0] = VertexInterp(isoLevel, ref cell, 0, 1); triangles[1].p[1] = VertexInterp(isoLevel, ref cell, 1, 3); triangles[1].p[2] = cell.p[1]; triangles[1].outerline[0] = 0; triangles[1].outerline[1] = 1; ntriang++; } if (case_11) { triangles[0] = new Triangle(); triangles[0].p[0] = cell.p[0]; triangles[0].p[1] = VertexInterp(isoLevel, ref cell, 1, 3); triangles[0].p[2] = cell.p[1]; // no outer line... ntriang++; triangles[1] = new Triangle(); triangles[1].p[0] = VertexInterp(isoLevel, ref cell, 2, 3); triangles[1].p[1] = VertexInterp(isoLevel, ref cell, 1, 3); triangles[1].p[2] = cell.p[0]; triangles[1].outerline[0] = 0; triangles[1].outerline[1] = 1; ntriang++; triangles[2] = new Triangle(); triangles[2].p[0] = cell.p[2]; triangles[2].p[1] = VertexInterp(isoLevel, ref cell, 2, 3); triangles[2].p[2] = cell.p[0]; // no outer line... ntriang++; } if (case_12) { triangles[0] = new Triangle(); triangles[0].p[0] = cell.p[2]; triangles[0].p[1] = cell.p[3]; triangles[0].p[2] = VertexInterp(isoLevel, ref cell, 0, 2); // no outer line... ntriang++; triangles[1] = new Triangle(); triangles[1].p[0] = cell.p[3]; triangles[1].p[1] = VertexInterp(isoLevel, ref cell, 1, 3); triangles[1].p[2] = VertexInterp(isoLevel, ref cell, 0, 2); triangles[1].outerline[0] = 1; triangles[1].outerline[1] = 2; ntriang++; } if (case_13) { triangles[0] = new Triangle(); triangles[0].p[0] = VertexInterp(isoLevel, ref cell, 0, 1); triangles[0].p[1] = cell.p[0]; triangles[0].p[2] = cell.p[2]; // no outer line... ntriang++; triangles[1] = new Triangle(); triangles[1].p[0] = VertexInterp(isoLevel, ref cell, 1, 3); triangles[1].p[1] = VertexInterp(isoLevel, ref cell, 0, 1); triangles[1].p[2] = cell.p[2]; triangles[1].outerline[0] = 0; triangles[1].outerline[1] = 1; ntriang++; triangles[2] = new Triangle(); triangles[2].p[0] = VertexInterp(isoLevel, ref cell, 1, 3); triangles[2].p[1] = cell.p[2]; triangles[2].p[2] = cell.p[3]; // no outer line... ntriang++; } if (case_14) { triangles[0] = new Triangle(); triangles[0].p[0] = cell.p[1]; triangles[0].p[1] = VertexInterp(isoLevel, ref cell, 0, 1); triangles[0].p[2] = cell.p[3]; // no outer line... ntriang++; triangles[1] = new Triangle(); triangles[1].p[0] = cell.p[3]; triangles[1].p[1] = VertexInterp(isoLevel, ref cell, 0, 1); triangles[1].p[2] = VertexInterp(isoLevel, ref cell, 0, 2); triangles[1].outerline[0] = 1; triangles[1].outerline[1] = 2; ntriang++; triangles[2] = new Triangle(); triangles[2].p[0] = VertexInterp(isoLevel, ref cell, 0, 2); triangles[2].p[1] = cell.p[2]; triangles[2].p[2] = cell.p[3]; // no outer line... ntriang++; } if (case_15) { triangles[0] = new Triangle(); triangles[0].p[0] = cell.p[2]; triangles[0].p[1] = cell.p[1]; triangles[0].p[2] = cell.p[0]; // no outer line... ntriang++; triangles[1] = new Triangle(); triangles[1].p[0] = cell.p[1]; triangles[1].p[1] = cell.p[2]; triangles[1].p[2] = cell.p[3]; // no outer line... ntriang++; } return ntriang; }
public void Start() { // grab the camera GameObject cam = GameObject.Find("Main Camera"); cam.transform.position = new Vector3(3,5,-1); cam.transform.rotation = Quaternion.Euler(60,0,0); // some 2d voxel data float[,] data = {{0,0,0,0,0,0},{0,1,1,1,1,0},{0,0,0,1,1,0},{0,0,0,0,1,0},{0,1,0,1,1,0},{0,1,1,0,1,0},{0,1,1,1,1,0},{0,0,0,0,0,0},}; // prepare cell data cells = new SquareCell[data.GetLength(0)-1,data.GetLength(1)-1]; // put data in cells for (int i = 0; i < data.GetLength(0); i++) { for (int j = 0; j < data.GetLength(1); j++) { // do not process the edges of the data array since cell.dim + 1 == data.dim if (i < data.GetLength(0)-1 && j < data.GetLength(1)-1) { SquareCell cell = new SquareCell(); cell.p[0] = new Vector2(i,j); cell.p[1] = new Vector2(i+1,j); cell.p[2] = new Vector2(i,j+1); cell.p[3] = new Vector2(i+1,j+1); cell.val[0] = data[i,j]; cell.val[1] = data[i+1,j]; cell.val[2] = data[i,j+1]; cell.val[3] = data[i+1,j+1]; cells[i,j] = cell; } } } // create a gameobject Testg = new GameObject(); Testg.name = "msquare"; Testg.transform.position = Vector3.zero; Testg.transform.rotation = Quaternion.identity; // collision meshfilter MeshFilter mf = (MeshFilter) Testg.AddComponent(typeof(MeshFilter)); // normally you don't want to render the collision mesh MeshRenderer mr = (MeshRenderer) Testg.AddComponent(typeof(MeshRenderer)); mr.material.color = new Color(.5f,.6f,1f, 1f); // collider rigidbody... Testg.AddComponent(typeof(Rigidbody)); Testg.rigidbody.isKinematic = true; Testg.rigidbody.useGravity = true; Testg.rigidbody.mass = 10; Testg.rigidbody.drag = 0.1f; Testg.rigidbody.angularDrag = 0.4f; MeshCollider mc = (MeshCollider) Testg.AddComponent(typeof(MeshCollider)); mc.sharedMesh = mf.mesh; mc.convex = true; // create texture sub gameobject TestRenderg = new GameObject(); TestRenderg.transform.parent = Testg.transform; TestRenderg.name = "msquare__rendermesh"; TestRenderg.transform.position = Vector3.zero; TestRenderg.transform.rotation = Quaternion.identity; TestRenderg.AddComponent(typeof(MeshFilter)); MeshRenderer cmr = (MeshRenderer) TestRenderg.AddComponent(typeof(MeshRenderer)); cmr.material.color = new Color(1f,.6f,1f, 1f); }