Advertisement
SebastianLague

PCG 03 MeshGenerator

Mar 2nd, 2015
504
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.95 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4.  
  5. public class MeshGenerator : MonoBehaviour {
  6.  
  7.     public SquareGrid squareGrid;
  8.     List<Vector3> vertices;
  9.     List<int> triangles;
  10.  
  11.     public void GenerateMesh(int[,] map, float squareSize) {
  12.         squareGrid = new SquareGrid(map, squareSize);
  13.  
  14.         vertices = new List<Vector3>();
  15.         triangles = new List<int>();
  16.  
  17.         for (int x = 0; x < squareGrid.squares.GetLength(0); x ++) {
  18.             for (int y = 0; y < squareGrid.squares.GetLength(1); y ++) {
  19.                 TriangulateSquare(squareGrid.squares[x,y]);
  20.             }
  21.         }
  22.  
  23.         Mesh mesh = new Mesh();
  24.         GetComponent<MeshFilter>().mesh = mesh;
  25.  
  26.         mesh.vertices = vertices.ToArray();
  27.         mesh.triangles = triangles.ToArray();
  28.         mesh.RecalculateNormals();
  29.  
  30.     }
  31.  
  32.     void TriangulateSquare(Square square) {
  33.         switch (square.configuration) {
  34.         case 0:
  35.             break;
  36.  
  37.         // 1 points:
  38.         case 1:
  39.             MeshFromPoints(square.centreBottom, square.bottomLeft, square.centreLeft);
  40.             break;
  41.         case 2:
  42.             MeshFromPoints(square.centreRight, square.bottomRight, square.centreBottom);
  43.             break;
  44.         case 4:
  45.             MeshFromPoints(square.centreTop, square.topRight, square.centreRight);
  46.             break;
  47.         case 8:
  48.             MeshFromPoints(square.topLeft, square.centreTop, square.centreLeft);
  49.             break;
  50.  
  51.         // 2 points:
  52.         case 3:
  53.             MeshFromPoints(square.centreRight, square.bottomRight, square.bottomLeft, square.centreLeft);
  54.             break;
  55.         case 6:
  56.             MeshFromPoints(square.centreTop, square.topRight, square.bottomRight, square.centreBottom);
  57.             break;
  58.         case 9:
  59.             MeshFromPoints(square.topLeft, square.centreTop, square.centreBottom, square.bottomLeft);
  60.             break;
  61.         case 12:
  62.             MeshFromPoints(square.topLeft, square.topRight, square.centreRight, square.centreLeft);
  63.             break;
  64.         case 5:
  65.             MeshFromPoints(square.centreTop, square.topRight, square.centreRight, square.centreBottom, square.bottomLeft, square.centreLeft);
  66.             break;
  67.         case 10:
  68.             MeshFromPoints(square.topLeft, square.centreTop, square.centreRight, square.bottomRight, square.centreBottom, square.centreLeft);
  69.             break;
  70.  
  71.         // 3 point:
  72.         case 7:
  73.             MeshFromPoints(square.centreTop, square.topRight, square.bottomRight, square.bottomLeft, square.centreLeft);
  74.             break;
  75.         case 11:
  76.             MeshFromPoints(square.topLeft, square.centreTop, square.centreRight, square.bottomRight, square.bottomLeft);
  77.             break;
  78.         case 13:
  79.             MeshFromPoints(square.topLeft, square.topRight, square.centreRight, square.centreBottom, square.bottomLeft);
  80.             break;
  81.         case 14:
  82.             MeshFromPoints(square.topLeft, square.topRight, square.bottomRight, square.centreBottom, square.centreLeft);
  83.             break;
  84.  
  85.         // 4 point:
  86.         case 15:
  87.             MeshFromPoints(square.topLeft, square.topRight, square.bottomRight, square.bottomLeft);
  88.             break;
  89.         }
  90.  
  91.     }
  92.  
  93.     void MeshFromPoints(params Node[] points) {
  94.         AssignVertices(points);
  95.  
  96.         if (points.Length >= 3)
  97.             CreateTriangle(points[0], points[1], points[2]);
  98.         if (points.Length >= 4)
  99.             CreateTriangle(points[0], points[2], points[3]);
  100.         if (points.Length >= 5)
  101.             CreateTriangle(points[0], points[3], points[4]);
  102.         if (points.Length >= 6)
  103.             CreateTriangle(points[0], points[4], points[5]);
  104.  
  105.     }
  106.  
  107.     void AssignVertices(Node[] points) {
  108.         for (int i = 0; i < points.Length; i ++) {
  109.             if (points[i].vertexIndex == -1) {
  110.                 points[i].vertexIndex = vertices.Count;
  111.                 vertices.Add(points[i].position);
  112.             }
  113.         }
  114.     }
  115.  
  116.     void CreateTriangle(Node a, Node b, Node c) {
  117.         triangles.Add(a.vertexIndex);
  118.         triangles.Add(b.vertexIndex);
  119.         triangles.Add(c.vertexIndex);
  120.     }
  121.  
  122.     void OnDrawGizmos() {
  123.         /*
  124.         if (squareGrid != null) {
  125.             for (int x = 0; x < squareGrid.squares.GetLength(0); x ++) {
  126.                 for (int y = 0; y < squareGrid.squares.GetLength(1); y ++) {
  127.  
  128.                     Gizmos.color = (squareGrid.squares[x,y].topLeft.active)?Color.black:Color.white;
  129.                     Gizmos.DrawCube(squareGrid.squares[x,y].topLeft.position, Vector3.one * .4f);
  130.  
  131.                     Gizmos.color = (squareGrid.squares[x,y].topRight.active)?Color.black:Color.white;
  132.                     Gizmos.DrawCube(squareGrid.squares[x,y].topRight.position, Vector3.one * .4f);
  133.  
  134.                     Gizmos.color = (squareGrid.squares[x,y].bottomRight.active)?Color.black:Color.white;
  135.                     Gizmos.DrawCube(squareGrid.squares[x,y].bottomRight.position, Vector3.one * .4f);
  136.  
  137.                     Gizmos.color = (squareGrid.squares[x,y].bottomLeft.active)?Color.black:Color.white;
  138.                     Gizmos.DrawCube(squareGrid.squares[x,y].bottomLeft.position, Vector3.one * .4f);
  139.  
  140.  
  141.                     Gizmos.color = Color.grey;
  142.                     Gizmos.DrawCube(squareGrid.squares[x,y].centreTop.position, Vector3.one * .15f);
  143.                     Gizmos.DrawCube(squareGrid.squares[x,y].centreRight.position, Vector3.one * .15f);
  144.                     Gizmos.DrawCube(squareGrid.squares[x,y].centreBottom.position, Vector3.one * .15f);
  145.                     Gizmos.DrawCube(squareGrid.squares[x,y].centreLeft.position, Vector3.one * .15f);
  146.  
  147.                 }
  148.             }
  149.         }
  150.         */
  151.     }
  152.    
  153.     public class SquareGrid {
  154.         public Square[,] squares;
  155.  
  156.         public SquareGrid(int[,] map, float squareSize) {
  157.             int nodeCountX = map.GetLength(0);
  158.             int nodeCountY = map.GetLength(1);
  159.             float mapWidth = nodeCountX * squareSize;
  160.             float mapHeight = nodeCountY * squareSize;
  161.  
  162.             ControlNode[,] controlNodes = new ControlNode[nodeCountX,nodeCountY];
  163.  
  164.             for (int x = 0; x < nodeCountX; x ++) {
  165.                 for (int y = 0; y < nodeCountY; y ++) {
  166.                     Vector3 pos = new Vector3(-mapWidth/2 + x * squareSize + squareSize/2, 0, -mapHeight/2 + y * squareSize + squareSize/2);
  167.                     controlNodes[x,y] = new ControlNode(pos,map[x,y] == 1, squareSize);
  168.                 }
  169.             }
  170.  
  171.             squares = new Square[nodeCountX -1,nodeCountY -1];
  172.             for (int x = 0; x < nodeCountX-1; x ++) {
  173.                 for (int y = 0; y < nodeCountY-1; y ++) {
  174.                     squares[x,y] = new Square(controlNodes[x,y+1], controlNodes[x+1,y+1], controlNodes[x+1,y], controlNodes[x,y]);
  175.                 }
  176.             }
  177.  
  178.         }
  179.     }
  180.    
  181.     public class Square {
  182.  
  183.         public ControlNode topLeft, topRight, bottomRight, bottomLeft;
  184.         public Node centreTop, centreRight, centreBottom, centreLeft;
  185.         public int configuration;
  186.  
  187.         public Square (ControlNode _topLeft, ControlNode _topRight, ControlNode _bottomRight, ControlNode _bottomLeft) {
  188.             topLeft = _topLeft;
  189.             topRight = _topRight;
  190.             bottomRight = _bottomRight;
  191.             bottomLeft = _bottomLeft;
  192.  
  193.             centreTop = topLeft.right;
  194.             centreRight = bottomRight.above;
  195.             centreBottom = bottomLeft.right;
  196.             centreLeft = bottomLeft.above;
  197.  
  198.             if (topLeft.active)
  199.                 configuration += 8;
  200.             if (topRight.active)
  201.                 configuration += 4;
  202.             if (bottomRight.active)
  203.                 configuration += 2;
  204.             if (bottomLeft.active)
  205.                 configuration += 1;
  206.         }
  207.  
  208.     }
  209.  
  210.     public class Node {
  211.         public Vector3 position;
  212.         public int vertexIndex = -1;
  213.  
  214.         public Node(Vector3 _pos) {
  215.             position = _pos;
  216.         }
  217.     }
  218.  
  219.     public class ControlNode : Node {
  220.  
  221.         public bool active;
  222.         public Node above, right;
  223.  
  224.         public ControlNode(Vector3 _pos, bool _active, float squareSize) : base(_pos) {
  225.             active = _active;
  226.             above = new Node(position + Vector3.forward * squareSize/2f);
  227.             right = new Node(position + Vector3.right * squareSize/2f);
  228.         }
  229.  
  230.     }
  231. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement