Exemple #1
0
 public MeshDataClass GetWallsData()
 {
     if (createWalls)
     {
         MeshDataClass toReturn = new MeshDataClass {
             vertices = wallVertices, triangles = wallTriangles
         };
         return(toReturn);
     }
     else
     {
         Debug.Log("Terrain generated without walls. Can't return walls mesh data.");
         MeshDataClass toReturn = new MeshDataClass
         {
             vertices = new List <Vector3>(), triangles = new List <int>()
         };
         return(toReturn);
     }
 }
Exemple #2
0
        public MeshDataClass GenerateMesh(bool[,] map, bool useException, float _minX, float _maxX, float _minY, float _maxY, float squareSize, float _height, bool invert, bool calculateWalls, float _wallsHeight)
        {
            squareGrid         = new SquareGrid(map, squareSize, invert);
            triangleDictionary = new Dictionary <int, List <Triangle> >();
            checkedVertices    = new HashSet <int>();
            outlines           = new List <List <int> >();
            vertices           = new List <Vector3>();
            triangles          = new List <int>();
            createWalls        = false;
            wallVertices       = new List <Vector3>();
            wallTriangles      = new List <int>();
            wallUV             = new List <Vector2>();
            totalWallLength    = 0f;
            height             = _height;
            wallHeight         = _wallsHeight;
            minX = _minX;
            maxX = _maxX;
            minY = _minY;
            maxY = _maxY;

            for (int x = 0; x < squareGrid.squares.GetLength(0); x++)
            {
                for (int y = 0; y < squareGrid.squares.GetLength(1); y++)
                {
                    TriangulateSquare(squareGrid.squares[x, y], useException);
                }
            }

            MeshDataClass toRetrun = new MeshDataClass {
                vertices = vertices, triangles = triangles
            };

            if (calculateWalls)
            {
                CreateWallMesh();
            }

            return(toRetrun);
        }
Exemple #3
0
        WG_LocationController EmitSegment(int u, int v, float segmentSize, float meshSquareSize, Transform root, bool[,] map, Material floorMaterial, Material wallsMaterial, float height, float uvPadding)
        {
            //create game object
            GameObject location = new GameObject()
            {
                name = "location_" + u.ToString() + "_" + v.ToString()
            };

            location.transform.SetParent(root);
            location.transform.position = new Vector3(u * segmentSize, 0.0f, v * segmentSize);
            WG_MarchingSquares marchingSquares = new WG_MarchingSquares();
            MeshDataClass      mountainsData   = marchingSquares.GenerateMesh(map, false, -segmentSize / 2, segmentSize / 2, -segmentSize / 2, segmentSize / 2, meshSquareSize, height, false, false, 0f);
            MeshDataClass      floorData       = marchingSquares.GenerateMesh(map, true, -segmentSize / 2, segmentSize / 2, -segmentSize / 2, segmentSize / 2, meshSquareSize, 0, true, true, height);
            //get walls vertices and triangles from generaton of the floor
            MeshDataClass wallsData = marchingSquares.GetWallsData();

            //union ground and mountains
            Vector3[] vertices = new Vector3[mountainsData.vertices.Count + floorData.vertices.Count];
            int       mountainsVerticesCount = mountainsData.vertices.Count;

            for (int i = 0; i < mountainsVerticesCount; i++)
            {
                vertices[i] = mountainsData.vertices[i];
            }

            for (int i = 0; i < floorData.vertices.Count; i++)
            {
                vertices[mountainsVerticesCount + i] = floorData.vertices[i];
            }
            //re-enumerate triangles
            int[] triangles = new int[mountainsData.triangles.Count + floorData.triangles.Count];
            int   mountainsTrianglesCount = mountainsData.triangles.Count;

            for (int i = 0; i < mountainsTrianglesCount; i++)
            {
                triangles[i] = mountainsData.triangles[i];
            }

            for (int i = 0; i < floorData.triangles.Count; i++)
            {
                triangles[mountainsTrianglesCount + i] = floorData.triangles[i] + mountainsVerticesCount;
            }
            GameObject groundGO = new GameObject("Ground")
            {
                isStatic = true
            };

            groundGO.transform.SetParent(location.transform, false);
            MeshRenderer groundRenderer = groundGO.AddComponent <MeshRenderer>();

            groundRenderer.material = floorMaterial;
            Mesh groundMesh = new Mesh()
            {
                vertices = vertices, triangles = triangles
            };

            groundMesh.Simplify();
            groundMesh.RecalculateNormals();
            //ground uv
            Vector2[] groundUV       = new Vector2[groundMesh.vertexCount];
            Vector2[] groundUV2      = new Vector2[groundMesh.vertexCount];
            Vector3[] groundVertices = groundMesh.vertices;
            Vector2[] vertexNormals  = marchingSquares.GetVertexNormals(groundMesh.vertices, groundMesh.triangles);
            for (int i = 0; i < groundVertices.Length; i++)
            {
                groundUV[i]  = new Vector2(0.5f + groundVertices[i].x / segmentSize, 0.5f + groundVertices[i].z / segmentSize);
                groundUV2[i] = groundUV[i] - uvPadding * vertexNormals[i];
            }

            groundMesh.uv  = groundUV;
            groundMesh.uv2 = groundUV2;

            MeshFilter groundFilter = groundGO.AddComponent <MeshFilter>();

            groundFilter.mesh = groundMesh;

            //next walls
            bool       createWalls = false;
            GameObject wallsGO     = new GameObject("Walls")
            {
                isStatic = true
            };

            if (wallsData.vertices.Count > 0)
            {
                createWalls = true;
                wallsGO.transform.SetParent(location.transform, false);
                MeshRenderer wallsRenderer = wallsGO.AddComponent <MeshRenderer>();
                wallsRenderer.material = wallsMaterial;
                Mesh wallsMesh = new Mesh()
                {
                    vertices = wallsData.vertices.ToArray(), triangles = wallsData.triangles.ToArray()
                };

                wallsMesh.RecalculateNormals();
                //next we should calculate uv coordinates
                //all polygons are separate 4-sided polygons
                Vector2[] wallsUV = marchingSquares.GetWallsUV();
                Vector2[] uv1     = new Vector2[wallsUV.Length];
                Vector2[] uv2     = new Vector2[wallsUV.Length];
                //uv2 should be fit to the square [0, 1]x[0, 1]
                //for uv1 rescale 1 to walls height
                float wallLength = marchingSquares.GetWallLength();
                for (int i = 0; i < wallsUV.Length; i++)
                {
                    Vector2 uv = wallsUV[i];
                    uv1[i] = new Vector2(uv.x / height, uv.y);
                    uv2[i] = new Vector2(uv.x / wallLength, uv.y);
                }

                wallsMesh.uv  = uv1;
                wallsMesh.uv2 = uv2;

                MeshFilter wallsFilter = wallsGO.AddComponent <MeshFilter>();
                wallsFilter.mesh = wallsMesh;
            }


            WG_LocationController locationController = location.AddComponent <WG_LocationController>();

            locationController.groundGO = groundGO;
            locationController.wallsGO  = createWalls ? wallsGO : null;
            locationController.u        = u;
            locationController.v        = v;

            if (!createWalls)
            {
                UnityEngine.Object.DestroyImmediate(wallsGO);
            }

            return(locationController);
        }