예제 #1
0
    private void AddWallInfo(int i, int j)
    {
        for (int k = 0; k < vertsInStack.Count; k++)
        {
            VertInStack  vis = vertsInStack[k];
            CellVertInfo cvi = cellVertInfos[(vis.coords.y - cyMin) * cw + (vis.coords.x - cxMin)];

            if (vis.cell.state == MapCell.State.Full)
            {
                for (int l = 0; l < vertsInStack.Count; l++)
                {
                    VertInStack vis2 = vertsInStack[l];
                    if (vis2.cell.state == MapCell.State.Excavated)
                    {
                        HexXY diff     = vis2.coords - vis.coords;
                        int   neighIdx = HexXY.DiffToNeighIndex(diff.x, diff.y);
                        cvi.WallVertices[neighIdx].High.Add(vis.mesh.vertices[vis.vidx]);
                        cvi.WallVertices[neighIdx].Low.Add(vis2.mesh.vertices[vis2.vidx]);
                        cvi.WallVertices[neighIdx].GridCoords.Add(new Vector2Int(i, j));
                        cvi.WallCount++;
                    }
                }
            }
        }
    }
예제 #2
0
    public HexMeshGenerator(int patchSize, int subDivsShift)
    {
        Debug.Assert((patchSize % 3) == 0);

        this.patchSize    = patchSize;
        this.subDivsShift = subDivsShift;
        this.subDivs      = 1 << subDivsShift;
        this.subDivsMask  = subDivs - 1;

        this.cxMin = 0;
        this.cyMin = -patchSize / 3;
        this.cw    = patchSize + 1;
        this.ch    = 2 * patchSize / 3 + 1;

        this.subdivRhex = rhex / subDivs;
        this.subdivRhey = rhey / subDivs;

        this.cellVertInfos = new CellVertInfo[cw * ch];
        for (int i = 0; i < ch; i++)
        {
            for (int j = 0; j < cw; j++)
            {
                CellVertInfo cvi = new CellVertInfo(new HexXY(cxMin + j, cyMin + i));
                this.cellVertInfos[i * cw + j] = cvi;
            }
        }
        this.vertsInStack = new List <VertInStack>(3);

        noise = new PerlinNoise();
    }
예제 #3
0
    private void AddNearCellVertices(int row, int col, HexXY cellCoords, MapCell cell)
    {
        MeshData mesh = selectCellMesh(cell);

        int sharedIdx = -1;

        for (int l = 0; l < vertsInStack.Count; l++)
        {
            if (vertsInStack[l].mesh == mesh)
            {
                sharedIdx = vertsInStack[l].vidx;
                break;
            }
        }

        int idx;

        if (sharedIdx == -1)
        {
            Vector2 patchOffset = patchOffsetX * patchSize * rhex + patchOffsetY * patchSize * rhey;

            idx = mesh.vertices.Count;
            Vector2 planeCoords = row * subdivRhey + col * subdivRhex;
            float   y           = cell.state == MapCell.State.Full ? 1 : 0;
            Vector3 vertex      = new Vector3(planeCoords.x, y, planeCoords.y);

            //TODO: move noise out
            float             noiseStrength = 0.1f;
            PerlinNoiseSample vNoise        = noise.Perlin2D(patchOffset + planeCoords, 0.5f);
            vertex.y += vNoise.value * noiseStrength;

            mesh.vertices.Add(vertex);
            Vector2 uvPos = patchOffset + new Vector2(planeCoords.x, planeCoords.y);
            mesh.uvs.Add(uvPos);

            Vector3 normal = new Vector3(-vNoise.derivative.x * noiseStrength, 1, -vNoise.derivative.y * noiseStrength).normalized;
            mesh.normals.Add(normal);
        }
        else
        {
            idx = sharedIdx;
        }

        vertsInStack.Add(new VertInStack()
        {
            cell = cell, mesh = mesh, vidx = idx, coords = cellCoords
        });
        CellVertInfo cvi = cellVertInfos[(cellCoords.y - cyMin) * cw + (cellCoords.x - cxMin)];

        cvi.SetMesh(mesh);
        cvi.AddIdx(row, idx);
    }
예제 #4
0
    public void GenerateWalls(MeshData wallMesh)
    {
        int nextIdx = 0;

        int cw = patchSize + 1;
        int ch = 2 * patchSize / 3 + 1;

        for (int i = 0; i < ch; i++)
        {
            for (int j = 0; j < cw; j++)
            {
                CellVertInfo cvi = cellVertInfos[i * cw + j];
                if (cvi.WallCount > 1)
                {
                    for (int k = 0; k < 6; k++)
                    {
                        WallVerticesInfo wis = cvi.WallVertices[k];

                        if (wis.High.Count < 2)
                        {
                            continue;
                        }

                        for (int l = 0; l < wis.High.Count; l++)
                        {
                            //Verts
                            Vector3 highVert = wis.High[l];
                            Vector3 lowVert  = wis.Low[l];

                            wallMesh.vertices.Add(highVert);
                            wallMesh.vertices.Add(lowVert);

                            //UVs
                            Vector2Int gridCoords = wis.GridCoords[l];

                            gridCoords.x += patchOffsetX * patchSize * subDivs;
                            gridCoords.y += patchOffsetY * patchSize * subDivs;

                            float u = WallUForGridCoords(gridCoords);
                            wallMesh.uvs.Add(new Vector2(u, 1));
                            wallMesh.uvs.Add(new Vector2(u, 0));

                            //Normals
                            //TODO: just neigbours for now, can smooth later if needed
                            Vector3 highNeigh;
                            if (l == 0)
                            {
                                highNeigh = wis.High[l + 1];
                            }
                            else
                            {
                                highNeigh = wis.High[l - 1];
                            }

                            Vector3 normal = Vector3.Cross(highNeigh - highVert, lowVert - highVert);
                            if (l > 0)
                            {
                                normal = -normal;
                            }
                            if (!(k >= 1 && k <= 3))
                            {
                                normal = -normal;
                            }

                            normal = normal.normalized;
                            wallMesh.normals.Add(normal);
                            wallMesh.normals.Add(normal);
                        }

                        for (int l = 0; l < wis.High.Count - 1; l++)
                        {
                            //Cut 0,0 outermost walls (duplicate walls in different patches cause z-fighting
                            Vector2Int gridCoords0 = wis.GridCoords[l];
                            Vector2Int gridCoords1 = wis.GridCoords[l + 1];
                            if ((gridCoords0.x == 0 && gridCoords1.x == 0) || (gridCoords0.y == 0 && gridCoords1.y == 0))
                            {
                                nextIdx += 2;
                                continue;
                            }

                            //Different winding order due to wall vertices
                            //filling order in main mesh generation above
                            if (k >= 1 && k <= 3)
                            {
                                wallMesh.triangles.Add(nextIdx);
                                wallMesh.triangles.Add(nextIdx + 3);
                                wallMesh.triangles.Add(nextIdx + 1);

                                wallMesh.triangles.Add(nextIdx);
                                wallMesh.triangles.Add(nextIdx + 2);
                                wallMesh.triangles.Add(nextIdx + 3);
                            }
                            else
                            {
                                wallMesh.triangles.Add(nextIdx);
                                wallMesh.triangles.Add(nextIdx + 1);
                                wallMesh.triangles.Add(nextIdx + 3);

                                wallMesh.triangles.Add(nextIdx);
                                wallMesh.triangles.Add(nextIdx + 3);
                                wallMesh.triangles.Add(nextIdx + 2);
                            }

                            nextIdx += 2;
                        }

                        nextIdx = wallMesh.vertices.Count;
                    }
                }
            }
        }
    }
예제 #5
0
    private void FillTriangleIndices(CellVertInfo cvi)
    {
        MeshData mesh = cvi.Mesh;

        for (int r = 0; r < cvi.RowStarts.Count - 1; r++)
        {
            int rowStart          = cvi.RowStarts[r];
            int nextRowStart      = cvi.RowStarts[r + 1];
            int afterNextRowStart = r == cvi.RowStarts.Count - 2 ? cvi.Idxs.Count : cvi.RowStarts[r + 2];

            int rowLen     = nextRowStart - rowStart;
            int nextRowLen = afterNextRowStart - nextRowStart;

            //TODO: simplify cases?
            if (rowLen == nextRowLen) //this rhombus part always leans to the right
            {
                for (int k = 0; k < rowLen - 1; k++)
                {
                    mesh.triangles.Add(cvi.Idxs[rowStart + k]);
                    mesh.triangles.Add(cvi.Idxs[nextRowStart + k]);
                    mesh.triangles.Add(cvi.Idxs[rowStart + k + 1]);

                    mesh.triangles.Add(cvi.Idxs[rowStart + k + 1]);
                    mesh.triangles.Add(cvi.Idxs[nextRowStart + k]);
                    mesh.triangles.Add(cvi.Idxs[nextRowStart + k + 1]);
                }
            }
            else if (rowLen < nextRowLen)
            {
                mesh.triangles.Add(cvi.Idxs[rowStart]);
                mesh.triangles.Add(cvi.Idxs[nextRowStart]);
                mesh.triangles.Add(cvi.Idxs[nextRowStart + 1]);

                for (int k = 0; k < rowLen - 1; k++)
                {
                    mesh.triangles.Add(cvi.Idxs[rowStart + k]);
                    mesh.triangles.Add(cvi.Idxs[nextRowStart + k + 1]);
                    mesh.triangles.Add(cvi.Idxs[rowStart + k + 1]);

                    mesh.triangles.Add(cvi.Idxs[rowStart + k + 1]);
                    mesh.triangles.Add(cvi.Idxs[nextRowStart + k + 1]);
                    mesh.triangles.Add(cvi.Idxs[nextRowStart + k + 2]);
                }
            }
            else
            {
                for (int k = 0; k < rowLen - 1; k++)
                {
                    mesh.triangles.Add(cvi.Idxs[rowStart + k]);
                    mesh.triangles.Add(cvi.Idxs[nextRowStart + k]);
                    mesh.triangles.Add(cvi.Idxs[rowStart + k + 1]);

                    if (k < rowLen - 2)
                    {
                        mesh.triangles.Add(cvi.Idxs[rowStart + k + 1]);
                        mesh.triangles.Add(cvi.Idxs[nextRowStart + k]);
                        mesh.triangles.Add(cvi.Idxs[nextRowStart + k + 1]);
                    }
                }
            }
        }
    }