コード例 #1
0
    private void TriangulateEdgeStripRoads(
        EdgeVertices edge1,
        Color weight1,
        float index1,
        EdgeVertices edge2,
        Color weight2,
        float index2,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer roads
        )
    {
        Vector3 indices;

        indices.x = indices.z = index1;
        indices.y = index2;

        TriangulateRoadSegment(
            edge1.vertex2,
            edge1.vertex3,
            edge1.vertex4,
            edge2.vertex2,
            edge2.vertex3,
            edge2.vertex4,
            weight1,
            weight2,
            indices,
            hexOuterRadius,
            wrapSize,
            roads
            );
    }
コード例 #2
0
    private void TriangulateEdgeTerracesRoad(
        EdgeVertices begin,
        Hex beginHex,
        EdgeVertices end,
        Hex endHex,
        bool hasRoad,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer roads
        )
    {
        EdgeVertices edge2   = EdgeVertices.TerraceLerp(begin, end, 1);
        Color        weight2 = HexagonPoint.TerraceLerp(_weights1, _weights2, 1);
        float        index1  = beginHex.Index;
        float        index2  = endHex.Index;

        TriangulateEdgeStripRoads(
            begin,
            _weights1,
            index1,
            edge2,
            weight2,
            index2,
            hexOuterRadius,
            wrapSize,
            roads
            );

        for (int i = 2; i < HexagonPoint.terraceSteps; i++)
        {
            EdgeVertices edge1   = edge2;
            Color        weight1 = weight2;
            edge2   = EdgeVertices.TerraceLerp(begin, end, i);
            weight2 = HexagonPoint.TerraceLerp(_weights1, _weights2, i);

            TriangulateEdgeStripRoads(
                edge1,
                weight1,
                index1,
                edge2,
                weight2,
                index2,
                hexOuterRadius,
                wrapSize,
                roads
                );
        }

        TriangulateEdgeStripRoads(
            edge2,
            weight2,
            index1,
            end,
            _weights2,
            index2,
            hexOuterRadius,
            wrapSize,
            roads
            );
    }
コード例 #3
0
    public static MapMeshChunkLayer CreateEmpty(
        Material material,
        bool useCollider,
        bool useHexData,
        bool useUVCoordinates,
        bool useUV2Coordinates
        )
    {
        GameObject        resultObj  = new GameObject("Map Mesh Chunk Layer");
        MapMeshChunkLayer resultMono = resultObj.AddComponent <MapMeshChunkLayer>();

        resultMono.GetComponent <MeshRenderer>().material = material;
        resultMono._useCollider = useCollider;

        if (useCollider)
        {
            resultMono._meshCollider =
                resultObj.AddComponent <MeshCollider>();
        }

        resultMono._useHexData        = useHexData;
        resultMono._useUVCoordinates  = useUVCoordinates;
        resultMono._useUV2Coordinates = useUV2Coordinates;

        return(resultMono);
    }
コード例 #4
0
    private void TriangulateRoadEdge(
        Vector3 center,
        Vector3 middleLeft,
        Vector3 middleRight,
        float index,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer roads
        )
    {
        roads.AddTrianglePerturbed(
            center,
            middleLeft,
            middleRight,
            hexOuterRadius,
            wrapSize
            );

        roads.AddTriangleUV(
            new Vector2(1f, 0f),
            new Vector2(0f, 0f),
            new Vector2(0f, 0f)
            );

        Vector3 indices;

        indices.x = indices.y = indices.z = index;
        roads.AddTriangleHexData(indices, _weights1);
    }
コード例 #5
0
 private void TriangulateRiverQuad(
     Vector3 vertex1,
     Vector3 vertex2,
     Vector3 vertex3,
     Vector3 vertex4,
     float y,
     float v,
     bool reversed,
     Vector3 indices,
     float hexOuterRadius,
     int wrapSize,
     MapMeshChunkLayer rivers
     )
 {
     TriangulateRiverQuad(
         vertex1,
         vertex2,
         vertex3,
         vertex4,
         y, y, v,
         reversed,
         indices,
         hexOuterRadius,
         wrapSize,
         rivers
         );
 }
コード例 #6
0
    private void TriangulateEdgeStripTerrain(
        EdgeVertices edge1,
        Color weight1,
        float index1,
        EdgeVertices edge2,
        Color weight2,
        float index2,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer terrain
        )
    {
        terrain.AddQuadPerturbed(
            edge1.vertex1,
            edge1.vertex2,
            edge2.vertex1,
            edge2.vertex2,
            hexOuterRadius,
            wrapSize
            );

        terrain.AddQuadPerturbed(
            edge1.vertex2,
            edge1.vertex3,
            edge2.vertex2,
            edge2.vertex3,
            hexOuterRadius,
            wrapSize
            );

        terrain.AddQuadPerturbed(
            edge1.vertex3,
            edge1.vertex4,
            edge2.vertex3,
            edge2.vertex4,
            hexOuterRadius,
            wrapSize
            );

        terrain.AddQuadPerturbed(
            edge1.vertex4,
            edge1.vertex5,
            edge2.vertex4,
            edge2.vertex5,
            hexOuterRadius,
            wrapSize
            );

        Vector3 indices;

        indices.x = indices.z = index1;
        indices.y = index2;

        terrain.AddQuadHexData(indices, weight1, weight2);
        terrain.AddQuadHexData(indices, weight1, weight2);
        terrain.AddQuadHexData(indices, weight1, weight2);
        terrain.AddQuadHexData(indices, weight1, weight2);
    }
コード例 #7
0
    private void TriangulateWaterfallInWater(
        Vector3 vertex1,
        Vector3 vertex2,
        Vector3 vertex3,
        Vector3 vertex4,
        float y1,
        float y2,
        float waterY,
        Vector3 indices,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer rivers
        )
    {
        vertex1.y = vertex2.y = y1;
        vertex3.y = vertex4.y = y2;

        vertex1 = HexagonPoint.Perturb(
            vertex1,
            hexOuterRadius,
            wrapSize
            );

        vertex2 = HexagonPoint.Perturb(
            vertex2,
            hexOuterRadius,
            wrapSize
            );

        vertex3 = HexagonPoint.Perturb(
            vertex3,
            hexOuterRadius,
            wrapSize
            );

        vertex4 = HexagonPoint.Perturb(
            vertex4,
            hexOuterRadius,
            wrapSize
            );

        float t = (waterY - y2) / (y1 - y2);

        vertex3 = Vector3.Lerp(vertex3, vertex1, t);
        vertex4 = Vector3.Lerp(vertex4, vertex2, t);

        rivers.AddQuadUnperturbed(
            vertex1,
            vertex2,
            vertex3,
            vertex4
            );

        rivers.AddQuadUV(0f, 1f, 0.8f, 1f);
        rivers.AddQuadHexData(indices, _weights1, _weights2);
    }
コード例 #8
0
    private void TriangulateWaterShoreWithRiver(
        EdgeVertices edge1,
        EdgeVertices edge2,
        bool incomingRiver,
        Vector3 indices,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer waterShore
        )
    {
        waterShore.AddTrianglePerturbed(
            edge2.vertex1,
            edge1.vertex2,
            edge1.vertex1,
            hexOuterRadius,
            wrapSize
            );

        waterShore.AddTrianglePerturbed(
            edge2.vertex5,
            edge1.vertex5,
            edge1.vertex4,
            hexOuterRadius,
            wrapSize
            );

        waterShore.AddTriangleUV
        (
            new Vector2(0f, 1f),
            new Vector2(0f, 0f),
            new Vector2(0f, 0f)
        );

        waterShore.AddTriangleUV
        (
            new Vector2(0f, 1f),
            new Vector2(0f, 0f),
            new Vector2(0f, 0f)
        );

        waterShore.AddTriangleHexData(
            indices,
            _weights2,
            _weights1,
            _weights1
            );

        waterShore.AddTriangleHexData(
            indices,
            _weights2,
            _weights1,
            _weights1
            );
    }
コード例 #9
0
    private TerrainTriangulationData TriangulateTerrainConnectionRoads(
        Hex source,
        Hex neighbor,
        TerrainTriangulationData data,
        HexDirections direction,
        HexRiverData riverData,
        Dictionary <HexDirections, bool> roadEdges,
        Dictionary <HexDirections, ElevationEdgeTypes> elevationEdgeTypes,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer roads
        )
    {
        bool hasRoad = roadEdges[direction];

        if (
//            hex.GetEdgeType(direction) == ElevationEdgeTypes.Slope
            elevationEdgeTypes[direction] == ElevationEdgeTypes.Slope
            )
        {
            if (hasRoad)
            {
                TriangulateEdgeTerracesRoads(
                    data.centerEdgeVertices,
                    source,
                    data.connectionEdgeVertices,
                    neighbor,
                    hasRoad,
                    hexOuterRadius,
                    wrapSize,
                    roads
                    );
            }
        }
        else
        {
            if (hasRoad)
            {
                TriangulateEdgeStripRoads(
                    data.centerEdgeVertices,
                    _weights1,
                    source.Index,
                    data.connectionEdgeVertices,
                    _weights2,
                    neighbor.Index,
                    hexOuterRadius,
                    wrapSize,
                    roads
                    );
            }
        }

        return(data);
    }
コード例 #10
0
    protected void TriangulateEdgeFan(
        Vector3 center,
        EdgeVertices edge,
        float index,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer terrain
        )
    {
        terrain.AddTrianglePerturbed(
            center,
            edge.vertex1,
            edge.vertex2,
            hexOuterRadius,
            wrapSize
            );

        terrain.AddTrianglePerturbed(
            center,
            edge.vertex2,
            edge.vertex3,
            hexOuterRadius,
            wrapSize
            );

        terrain.AddTrianglePerturbed(
            center,
            edge.vertex3,
            edge.vertex4,
            hexOuterRadius,
            wrapSize
            );

        terrain.AddTrianglePerturbed(
            center,
            edge.vertex4,
            edge.vertex5,
            hexOuterRadius,
            wrapSize
            );

        // All three cell indices corresponing to the sides of this
        // edge are of one cell.
        Vector3 indices;

        indices.x = indices.y = indices.z = index;

        terrain.AddTriangleHexData(indices, _weights1);
        terrain.AddTriangleHexData(indices, _weights1);
        terrain.AddTriangleHexData(indices, _weights1);
        terrain.AddTriangleHexData(indices, _weights1);
    }
コード例 #11
0
    private TerrainTriangulationData TriangulateCenterRiverQuads(
        Hex source,
        TerrainTriangulationData triangulationData,
        HexDirections direction,
        HexRiverData riverData,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer rivers
        )
    {
        bool reversed = riverData.HasIncomingRiverInDirection(
            direction
            );

        Vector3 centerHexIndices;

        centerHexIndices.x         =
            centerHexIndices.y     =
                centerHexIndices.z =
                    source.Index;

        TriangulateRiverQuad(
            triangulationData.riverCenterLeft,
            triangulationData.riverCenterRight,
            triangulationData.middleEdgeVertices.vertex2,
            triangulationData.middleEdgeVertices.vertex4,
            source.RiverSurfaceY,
            0.4f,
            reversed,
            centerHexIndices,
            hexOuterRadius,
            wrapSize,
            rivers
            );

        TriangulateRiverQuad(
            triangulationData.middleEdgeVertices.vertex2,
            triangulationData.middleEdgeVertices.vertex4,
            triangulationData.centerEdgeVertices.vertex2,
            triangulationData.centerEdgeVertices.vertex4,
            source.RiverSurfaceY,
            0.6f,
            reversed,
            centerHexIndices,
            hexOuterRadius,
            wrapSize,
            rivers
            );

        return(triangulationData);
    }
コード例 #12
0
    private TerrainTriangulationData TriangulateCenterRiverSurface(
        HexRiverData riverData,
        HexDirections direction,
        Hex source,
        TerrainTriangulationData data,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer rivers,
        Dictionary <HexDirections, bool> roadEdges
        )
    {
        if (riverData.HasRiver)
        {
            if (riverData.HasRiverInDirection(direction))
            {
// If the triangle has a river through the edge, lower center edge vertex
// to simulate stream bed.
                if (riverData.HasRiverStartOrEnd)
                {
                    if (!source.IsUnderwater)
                    {
                        data = TriangulateRiverBeginOrEndRiver(
                            source,
                            data,
                            riverData,
                            hexOuterRadius,
                            wrapSize,
                            rivers
                            );
                    }
                }
                else if (!source.IsUnderwater)
                {
                    data = TriangulateCenterRiverQuads(
                        source,
                        data,
                        direction,
                        riverData,
                        hexOuterRadius,
                        wrapSize,
                        rivers
                        );
                }
            }
        }

        return(data);
    }
コード例 #13
0
    private TerrainTriangulationData TriangulateRiverBeginOrEndTerrain(
        Hex source,
        TerrainTriangulationData data,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer terrain
        )
    {
        data.middleEdgeVertices = new EdgeVertices(
            Vector3.Lerp(
                data.terrainCenter,
                data.centerEdgeVertices.vertex1,
                0.5f
                ),
            Vector3.Lerp(
                data.terrainCenter,
                data.centerEdgeVertices.vertex5,
                0.5f
                )
            );

        data.middleEdgeVertices.vertex3.y = source.StreamBedY;

        TriangulateEdgeStripTerrain(
            data.middleEdgeVertices,
            _weights1,
            source.Index,
            data.centerEdgeVertices,
            _weights1,
            source.Index,
            hexOuterRadius,
            wrapSize,
            terrain
            );

        TriangulateEdgeFan(
            data.terrainCenter,
            data.middleEdgeVertices,
            source.Index,
            hexOuterRadius,
            wrapSize,
            terrain
            );

        return(data);
    }
コード例 #14
0
    private WaterTriangulationData TriangulateOpenWaterCenter(
        Hex source,
        WaterTriangulationData triangulationData,
        HexDirections direction,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer water
        )
    {
        triangulationData.waterSurfaceCornerLeft =
            triangulationData.waterSurfaceCenter +
            HexagonPoint.GetFirstWaterCorner(
                direction,
                hexOuterRadius
                );

        triangulationData.waterSurfaceCornerRight =
            triangulationData.waterSurfaceCenter +
            HexagonPoint.GetSecondWaterCorner(
                direction,
                hexOuterRadius
                );

        water.AddTrianglePerturbed(
            triangulationData.waterSurfaceCenter,
            triangulationData.waterSurfaceCornerLeft,
            triangulationData.waterSurfaceCornerRight,
            hexOuterRadius,
            wrapSize
            );

        Vector3 openWaterCenterIndices;

        openWaterCenterIndices.x         =
            openWaterCenterIndices.y     =
                openWaterCenterIndices.z =
                    source.Index;

        water.AddTriangleHexData(
            openWaterCenterIndices,
            _weights1
            );

        return(triangulationData);
    }
コード例 #15
0
    protected void TriangulateRoadSegment(
        Vector3 vertex1,
        Vector3 vertex2,
        Vector3 vertex3,
        Vector3 vertex4,
        Vector3 vertex5,
        Vector3 vertex6,
        Color weight1,
        Color weight2,
        Vector3 indices,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer roads
        )
    {
        roads.AddQuadPerturbed(
            vertex1,
            vertex2,
            vertex4,
            vertex5,
            hexOuterRadius,
            wrapSize
            );

        roads.AddQuadPerturbed(
            vertex2,
            vertex3,
            vertex5,
            vertex6,
            hexOuterRadius,
            wrapSize
            );

        roads.AddQuadUV(0f, 1f, 0f, 0f);
        roads.AddQuadUV(1f, 0f, 0f, 0f);

        roads.AddQuadHexData(indices, weight1, weight2);
        roads.AddQuadHexData(indices, weight1, weight2);
    }
コード例 #16
0
    private void TriangulateRoadWithoutRiver(
        Hex source,
        HexDirections direction,
        EdgeVertices edgeVertices,
        Dictionary <HexDirections, bool> roadEdges,
        Vector3 center,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer roads
        )
    {
        Vector2 interpolators = GetRoadInterpolators(
            source,
            direction,
            roadEdges
            );

        TriangulateRoad(
            center,
            Vector3.Lerp(
                center,
                edgeVertices.vertex1,
                interpolators.x
                ),
            Vector3.Lerp(
                center,
                edgeVertices.vertex5,
                interpolators.y
                ),
            edgeVertices,
//                hex.HasRoadThroughEdge(direction),
            roadEdges[direction],
            source.Index,
            hexOuterRadius,
            wrapSize,
            roads
            );
    }
コード例 #17
0
    private void TriangulateRiverQuad(
        Vector3 vertex1,
        Vector3 vertex2,
        Vector3 vertex3,
        Vector3 vertex4,
        float y1, float y2,
        float v,
        bool reversed,
        Vector3 indices,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer rivers
        )
    {
        vertex1.y = vertex2.y = y1;
        vertex3.y = vertex4.y = y2;

        rivers.AddQuadPerturbed(
            vertex1,
            vertex2,
            vertex3,
            vertex4,
            hexOuterRadius,
            wrapSize
            );

        if (reversed)
        {
            rivers.AddQuadUV(1f, 0f, 0.8f - v, 0.6f - v);
        }
        else
        {
            rivers.AddQuadUV(0f, 1f, v, v + 0.2f);
        }

        rivers.AddQuadHexData(indices, _weights1, _weights2);
    }
コード例 #18
0
    private TerrainTriangulationData TryTriangulateNeighborTerrainCorner(
        Hex source,
        Hex neighbor,
        TerrainTriangulationData data,
        HexDirections direction,
        Dictionary <HexDirections, Hex> neighbors,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer terrain,
        FeatureContainer features
        )
    {
        Hex nextNeighbor;

        if (
            neighbors.TryGetValue(
                direction.NextClockwise(),
                out nextNeighbor
                ) &&
            direction <= HexDirections.East
            )
        {
            TriangulateNeighborTerrainCorner(
                source,
                neighbor,
                nextNeighbor,
                direction,
                data,
                hexOuterRadius,
                wrapSize,
                terrain,
                features
                );
        }

        return(data);
    }
コード例 #19
0
    private TerrainTriangulationData TriangulateTerrainConnection(
        Hex source,
        Hex neighbor,
        TerrainTriangulationData data,
        HexDirections direction,
        HexRiverData riverData,
        Dictionary <HexDirections, bool> roadEdges,
        Dictionary <HexDirections, ElevationEdgeTypes> elevationEdgeTypes,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer terrain,
        FeatureContainer features
        )
    {
        if (riverData.HasRiverInDirection(direction))
        {
            data.connectionEdgeVertices.vertex3.y = neighbor.StreamBedY;
        }

        bool hasRoad = roadEdges[direction];

        if (
//            hex.GetEdgeType(direction) == ElevationEdgeTypes.Slope
            elevationEdgeTypes[direction] == ElevationEdgeTypes.Slope
            )
        {
            TriangulateEdgeTerracesTerrain(
                data.centerEdgeVertices,
                source,
                data.connectionEdgeVertices,
                neighbor,
                hexOuterRadius,
                wrapSize,
                terrain
                );
        }
        else
        {
            TriangulateEdgeStripTerrain(
                data.centerEdgeVertices,
                _weights1,
                source.Index,
                data.connectionEdgeVertices,
                _weights2,
                neighbor.Index,
                hexOuterRadius,
                wrapSize,
                terrain
                );
        }

        features.AddWall(
            data.centerEdgeVertices,
            source,
            data.connectionEdgeVertices,
            neighbor,
            riverData.HasRiverInDirection(direction),
            hasRoad,
            hexOuterRadius,
            wrapSize
            );

        return(data);
    }
コード例 #20
0
    private void TriangulateCornerTerraces(
        Vector3 begin,
        Hex beginHex,
        Vector3 left,
        Hex leftHex,
        Vector3 right,
        Hex rightHex,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer terrain
        )
    {
        Vector3 vertex3 = HexagonPoint.TerraceLerp(begin, left, 1);
        Vector3 vertex4 = HexagonPoint.TerraceLerp(begin, right, 1);
        Color   weight3 = HexagonPoint.TerraceLerp(_weights1, _weights2, 1);
        Color   weight4 = HexagonPoint.TerraceLerp(_weights1, _weights3, 1);

        Vector3 indices;

        indices.x = beginHex.Index;
        indices.y = leftHex.Index;
        indices.z = rightHex.Index;

        terrain.AddTrianglePerturbed(
            begin,
            vertex3,
            vertex4,
            hexOuterRadius,
            wrapSize
            );

        terrain.AddTriangleHexData(
            indices,
            _weights1,
            weight3,
            weight4
            );

        for (int i = 2; i < HexagonPoint.terraceSteps; i++)
        {
            Vector3 vertex1 = vertex3;
            Vector3 vertex2 = vertex4;
            Color   weight1 = weight3;
            Color   weight2 = weight4;

            vertex3 = HexagonPoint.TerraceLerp(begin, left, i);
            vertex4 = HexagonPoint.TerraceLerp(begin, right, i);
            weight3 = HexagonPoint.TerraceLerp(_weights1, _weights2, i);
            weight4 = HexagonPoint.TerraceLerp(_weights1, _weights3, i);

            terrain.AddQuadPerturbed(
                vertex1,
                vertex2,
                vertex3,
                vertex4,
                hexOuterRadius,
                wrapSize
                );

            terrain.AddQuadHexData(
                indices,
                weight1,
                weight2,
                weight3,
                weight4
                );
        }

        terrain.AddQuadPerturbed(
            vertex3,
            vertex4,
            left,
            right,
            hexOuterRadius,
            wrapSize
            );

        terrain.AddQuadHexData(
            indices,
            weight3,
            weight4,
            _weights2,
            _weights3
            );
    }
コード例 #21
0
    private TerrainTriangulationData TriangulateTerrainCenter(
        HexRiverData riverData,
        HexDirections direction,
        Hex source,
        TerrainTriangulationData data,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer terrain,
        FeatureContainer features,
        Dictionary <HexDirections, bool> roadEdges
        )
    {
        if (riverData.HasRiver)
        {
            if (riverData.HasRiverInDirection(direction))
            {
                data.centerEdgeVertices.vertex3.y = source.StreamBedY;

                if (riverData.HasRiverStartOrEnd)
                {
                    data = TriangulateRiverBeginOrEndTerrain(
                        source,
                        data,
                        hexOuterRadius,
                        wrapSize,
                        terrain
                        );
                }
                else
                {
                    data = TriangulateRiverBanks(
                        data,
                        riverData,
                        direction,
                        hexOuterRadius
                        );

                    data = TriangulateRiverTerrain(
                        source,
                        data,
                        hexOuterRadius,
                        wrapSize,
                        terrain
                        );
                }
            }
            else
            {
                data = TriangulateTerrainAdjacentToRiver(
                    source,
                    direction,
                    data,
                    roadEdges,
                    riverData,
                    hexOuterRadius,
                    wrapSize,
                    terrain,
                    features
                    );
            }
        }
        else
        {
            // Triangulate terrain center without river, basic edge fan.
            TriangulateEdgeFan(
                data.terrainCenter,
                data.centerEdgeVertices,
                source.Index,
                hexOuterRadius,
                wrapSize,
                terrain
                );

            if (
                !source.IsUnderwater &&
                !roadEdges[direction]
                )
            {
                features.AddFeature(
                    source,
                    (
                        data.terrainCenter +
                        data.centerEdgeVertices.vertex1 +
                        data.centerEdgeVertices.vertex5
                    ) * (1f / 3f),
                    hexOuterRadius,
                    wrapSize
                    );
            }
        }

        return(data);
    }
コード例 #22
0
    private void TriangulateTerrainCorner(
        Vector3 begin,
        Hex beginHex,
        Vector3 left,
        Hex leftHex,
        Vector3 right,
        Hex rightHex,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer terrain,
        FeatureContainer features
        )
    {
        ElevationEdgeTypes leftEdgeType  = beginHex.GetEdgeType(leftHex);
        ElevationEdgeTypes rightEdgeType = beginHex.GetEdgeType(rightHex);

        if (leftEdgeType == ElevationEdgeTypes.Slope)
        {
            if (rightEdgeType == ElevationEdgeTypes.Slope)
            {
// Corner is also a terrace. Slope-Slope-Flat.
                TriangulateCornerTerraces(
                    begin,
                    beginHex,
                    left,
                    leftHex,
                    right,
                    rightHex,
                    hexOuterRadius,
                    wrapSize,
                    terrain
                    );
            }

// If the right edge is flat, must terrace from left instead of bottom.
// Slope-Flat-Slope
            else if (rightEdgeType == ElevationEdgeTypes.Flat)
            {
                TriangulateCornerTerraces(
                    left,
                    leftHex,
                    right,
                    rightHex,
                    begin,
                    beginHex,
                    hexOuterRadius,
                    wrapSize,
                    terrain
                    );
            }
            else
            {
/* At least one edge is a cliff. Slope-Cliff-Slope or Slope-Cliff-Cliff. Standard case
 * because slope on left and flat on right.
 */
                TriangulateCornerTerracesCliff(
                    begin,
                    beginHex,
                    left,
                    leftHex,
                    right,
                    rightHex,
                    hexOuterRadius,
                    wrapSize,
                    terrain
                    );
            }
        }
        else if (rightEdgeType == ElevationEdgeTypes.Slope)
        {
            if (leftEdgeType == ElevationEdgeTypes.Flat)
            {
/* If the right edge is a slope, and the left edge is flat, must terrace from right instead
 * of bottom. Flat-Slope-Slope.
 */
                TriangulateCornerTerraces(
                    right,
                    rightHex,
                    begin,
                    beginHex,
                    left,
                    leftHex,
                    hexOuterRadius,
                    wrapSize,
                    terrain
                    );
            }
            else
            {
/* At least one edge is a cliff. Slope-Cliff-Slope or Slope-Cliff-Cliff. Mirror case because
 * slope on right and flat on left.
 */
                TriangulateCornerCliffTerraces(
                    begin,
                    beginHex,
                    left,
                    leftHex,
                    right,
                    rightHex,
                    hexOuterRadius,
                    wrapSize,
                    terrain
                    );
            }
        }

/* Neither the left or right hex edge type is a slope. If the right hex type of the left hex
 * is a slope, then terraces must be calculated for a corner between two cliff edges.
 * Cliff-Cliff-Slope Right, or Cliff-Cliff-Slope Left.
 */
        else if (leftHex.GetEdgeType(rightHex) == ElevationEdgeTypes.Slope)
        {
// If Cliff-Cliff-Slope-Left
            if (leftHex.elevation < rightHex.elevation)
            {
                TriangulateCornerCliffTerraces(
                    right,
                    rightHex,
                    begin,
                    beginHex,
                    left,
                    leftHex,
                    hexOuterRadius,
                    wrapSize,
                    terrain
                    );
            }

// If Cliff-Cliff-Slope-Right
            else
            {
                TriangulateCornerTerracesCliff(
                    left,
                    leftHex,
                    right,
                    rightHex,
                    begin,
                    beginHex,
                    hexOuterRadius,
                    wrapSize,
                    terrain
                    );
            }
        }

// Else all edges are cliffs. Simply draw a triangle.
        else
        {
            terrain.AddTrianglePerturbed(
                begin,
                left,
                right,
                hexOuterRadius,
                wrapSize
                );

            Vector3 indices;
            indices.x = beginHex.Index;
            indices.y = leftHex.Index;
            indices.z = rightHex.Index;

            terrain.AddTriangleHexData(
                indices,
                _weights1,
                _weights2,
                _weights3
                );
        }

        features.AddWall(
            begin,
            beginHex,
            left,
            leftHex,
            right,
            rightHex,
            hexOuterRadius,
            wrapSize
            );
    }
コード例 #23
0
    private TerrainTriangulationData TriangulateNeighborTerrainCorner(
        Hex source,
        Hex neighbor,
        Hex nextNeighbor,
        HexDirections direction,
        TerrainTriangulationData data,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer terrain,
        FeatureContainer features
        )
    {
// Create a 5th vertex and assign it with the elevation of the neighbor
// under consideration. This will be used as the final vertex in the
// triangle which fills the gap between bridges.
        Vector3 vertex5 =
            data.centerEdgeVertices.vertex5 + HexagonPoint.GetBridge(
                direction.NextClockwise(),
                hexOuterRadius
                );

        vertex5.y = nextNeighbor.Position.y;

        if (source.elevation <= neighbor.elevation)
        {
            if (source.elevation <= nextNeighbor.elevation)
            {
// This hex has lowest elevation, no rotation.
                TriangulateTerrainCorner(
                    data.centerEdgeVertices.vertex5,
                    source,
                    data.connectionEdgeVertices.vertex5,
                    neighbor,
                    vertex5,
                    nextNeighbor,
                    hexOuterRadius,
                    wrapSize,
                    terrain,
                    features
                    );
            }
            else
            {
// Next neighbor has lowest elevation, rotate counter-clockwise.
                TriangulateTerrainCorner(
                    vertex5,
                    nextNeighbor,
                    data.centerEdgeVertices.vertex5,
                    source,
                    data.connectionEdgeVertices.vertex5,
                    neighbor,
                    hexOuterRadius,
                    wrapSize,
                    terrain,
                    features
                    );
            }
        }
        else if (neighbor.elevation <= nextNeighbor.elevation)
        {
// Neighbor is lowest hex, rotate triangle clockwise.
            TriangulateTerrainCorner(
                data.connectionEdgeVertices.vertex5,
                neighbor,
                vertex5,
                nextNeighbor,
                data.centerEdgeVertices.vertex5,
                source,
                hexOuterRadius,
                wrapSize,
                terrain,
                features
                );
        }
        else
        {
// Next neighbor has lowest elevation, rotate counter-clockwise.
            TriangulateTerrainCorner(
                vertex5,
                nextNeighbor,
                data.centerEdgeVertices.vertex5,
                source,
                data.connectionEdgeVertices.vertex5,
                neighbor,
                hexOuterRadius,
                wrapSize,
                terrain,
                features
                );
        }

        return(data);
    }
コード例 #24
0
    private WaterTriangulationData TriangulateOpenWaterConnection(
        Hex source,
        Hex target,
        HexDirections direction,
        WaterTriangulationData waterTriData,
        TerrainTriangulationData terrainTriData,
        Dictionary <HexDirections, Hex> neighbors,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer water
        )
    {
        if (
            direction <= HexDirections.Southeast
            )
        {
            Vector3 bridge = HexagonPoint.GetWaterBridge(
                direction,
                hexOuterRadius
                );

            Vector3 edge1 = waterTriData.waterSurfaceCornerLeft + bridge;
            Vector3 edge2 = waterTriData.waterSurfaceCornerRight + bridge;

            water.AddQuadPerturbed(
                waterTriData.waterSurfaceCornerLeft,
                waterTriData.waterSurfaceCornerRight,
                edge1,
                edge2,
                hexOuterRadius,
                wrapSize
                );

            Vector3 openWaterIndices;
            openWaterIndices.x     =
                openWaterIndices.z =
                    source.Index;

            openWaterIndices.y = target.Index;

            water.AddQuadHexData(
                openWaterIndices,
                _weights1,
                _weights2
                );

            if (direction <= HexDirections.East)
            {
                Hex nextNeighbor;

                if (
                    neighbors.TryGetValue(
                        direction.NextClockwise(),
                        out nextNeighbor
                        ) &&
                    nextNeighbor.IsUnderwater
                    )
                {
                    water.AddTrianglePerturbed(
                        waterTriData.waterSurfaceCornerRight,
                        edge2,
                        waterTriData.waterSurfaceCornerRight +
                        HexagonPoint.GetWaterBridge(
                            direction.NextClockwise(),
                            hexOuterRadius
                            ),
                        hexOuterRadius,
                        wrapSize
                        );

                    openWaterIndices.z =
                        nextNeighbor.Index;

                    water.AddTriangleHexData(
                        openWaterIndices,
                        _weights1,
                        _weights2,
                        _weights3
                        );
                }
            }
        }

        return(waterTriData);
    }
コード例 #25
0
    private WaterTriangulationData TriangulateShoreOpenWater(
        Hex source,
        Hex target,
        Vector3 waterSurfaceCenter,
        EdgeVertices sourceWaterEdge,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer water,
        WaterTriangulationData triangulationData
        )
    {
        water.AddTrianglePerturbed(
            waterSurfaceCenter,
            sourceWaterEdge.vertex1,
            sourceWaterEdge.vertex2,
            hexOuterRadius,
            wrapSize
            );

        water.AddTrianglePerturbed(
            waterSurfaceCenter,
            sourceWaterEdge.vertex2,
            sourceWaterEdge.vertex3,
            hexOuterRadius,
            wrapSize
            );

        water.AddTrianglePerturbed(
            waterSurfaceCenter,
            sourceWaterEdge.vertex3,
            sourceWaterEdge.vertex4,
            hexOuterRadius,
            wrapSize
            );

        water.AddTrianglePerturbed(
            waterSurfaceCenter,
            sourceWaterEdge.vertex4,
            sourceWaterEdge.vertex5,
            hexOuterRadius,
            wrapSize
            );

        //            / | y
        //           /  |
        //           |  |
        //source x/z |  | target
        //           |  |
        //           \  |
        //            \ | y

        Vector3 waterShoreHexIndices;

        waterShoreHexIndices.x     =
            waterShoreHexIndices.z = source.Index;

        waterShoreHexIndices.y = target.Index;

        water.AddTriangleHexData(
            waterShoreHexIndices,
            _weights1
            );

        water.AddTriangleHexData(
            waterShoreHexIndices,
            _weights1
            );

        water.AddTriangleHexData(
            waterShoreHexIndices,
            _weights1
            );

        water.AddTriangleHexData(
            waterShoreHexIndices,
            _weights1
            );

        return(triangulationData);
    }
コード例 #26
0
    private void TriangulateCornerCliffTerraces(
        Vector3 begin,
        Hex beginHex,
        Vector3 left,
        Hex leftHex,
        Vector3 right,
        Hex rightHex,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer terrain
        )
    {
/* Set boundary distance to 1 elevation level above the bottom-most hex
 * in the case.
 */
        float boundaryDistance =
            1f / (leftHex.elevation - beginHex.elevation);

// If boundary distance becomes negative, CCSR and CCSL case will have strange behavior.
        if (boundaryDistance < 0)
        {
            boundaryDistance = -boundaryDistance;
        }

// Must interpolate between the perturbed points, not the original points.
        Vector3 boundary =
            Vector3.Lerp(
                HexagonPoint.Perturb(
                    begin,
                    hexOuterRadius,
                    wrapSize
                    ),
                HexagonPoint.Perturb(
                    left,
                    hexOuterRadius,
                    wrapSize
                    ),
                boundaryDistance
                );

        Color boundaryWeights =
            Color.Lerp(
                _weights1,
                _weights2,
                boundaryDistance
                );

        Vector3 indices;

        indices.x = beginHex.Index;
        indices.y = leftHex.Index;
        indices.z = rightHex.Index;

        TriangulateBoundaryTriangle(
            right,
            _weights3,
            begin,
            _weights1,
            boundary,
            boundaryWeights,
            indices,
            hexOuterRadius,
            wrapSize,
            terrain
            );

// Slope-Cliff-Slope. Triangulate a slope.
        if (leftHex.GetEdgeType(rightHex) == ElevationEdgeTypes.Slope)
        {
            TriangulateBoundaryTriangle(
                left,
                _weights2,
                right,
                _weights3,
                boundary,
                boundaryWeights,
                indices,
                hexOuterRadius,
                wrapSize,
                terrain
                );
        }

// Slope-Cliff-Cliff. Triangulate a cliff.
        else
        {
/* Add perturbation to all vertices except the boundary vertex
 * to handle the Slope-Cliff-Cliff case of the Cliff-Slope perturbation
 * problem.
 */
            terrain.AddTriangleUnperturbed(
                HexagonPoint.Perturb(
                    left,
                    hexOuterRadius,
                    wrapSize
                    ),
                HexagonPoint.Perturb(
                    right,
                    hexOuterRadius,
                    wrapSize
                    ),
                boundary
                );

            terrain.AddTriangleHexData(
                indices,
                _weights2,
                _weights3,
                boundaryWeights
                );
        }
    }
コード例 #27
0
    protected void TriangulateBoundaryTriangle(
        Vector3 begin,
        Color beginWeights,
        Vector3 left,
        Color leftWeights,
        Vector3 boundary,
        Color boundaryWeights,
        Vector3 indices,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer terrain
        )
    {
/* Immediately perturb vertex 2 as an optimization since it is not
 * being used to derive any other point.
 */
        Vector3 vertex2 =
            HexagonPoint.Perturb(
                HexagonPoint.TerraceLerp(begin, left, 1),
                hexOuterRadius,
                wrapSize
                );

        Color weight2 =
            HexagonPoint.TerraceLerp(
                beginWeights,
                leftWeights,
                1
                );

/* Perturb all vertices except the boundary vertex, to avoid moving
 * the vertex out of alignment with a cliff. vertex2 has already been
 * perturbed. Handles the Cliff-Slope-Slope and Slope-Cliff-Slope cases
 * of the Cliff-Slope perturbation problem.
 */
        terrain.AddTriangleUnperturbed(
            HexagonPoint.Perturb(
                begin,
                hexOuterRadius,
                wrapSize
                ),
            vertex2,
            boundary
            );

        terrain.AddTriangleHexData(
            indices,
            beginWeights,
            weight2,
            boundaryWeights
            );

        for (int i = 2; i < HexagonPoint.terraceSteps; i++)
        {
/* vertex2 has already been perturbed, need not pertub
 * vertex1 as it is derived from vertex2.
 */
            Vector3 vertex1 = vertex2;
            Color   weight1 = weight2;

            vertex2 = HexagonPoint.Perturb(
                HexagonPoint.TerraceLerp(begin, left, i),
                hexOuterRadius,
                wrapSize
                );

            weight2 = HexagonPoint.TerraceLerp(
                beginWeights,
                leftWeights,
                i
                );

            terrain.AddTriangleUnperturbed(vertex1, vertex2, boundary);

            terrain.AddTriangleHexData(
                indices,
                weight1,
                weight2,
                boundaryWeights
                );
        }

        terrain.AddTriangleUnperturbed(
            vertex2,
            HexagonPoint.Perturb(
                left,
                hexOuterRadius,
                wrapSize
                ),
            boundary
            );
        terrain.AddTriangleHexData(indices, weight2, leftWeights, boundaryWeights);
    }
コード例 #28
0
    private TerrainTriangulationData TriangulateRiverTerrain(
        Hex source,
        TerrainTriangulationData triangulationData,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer terrain
        )
    {
        TriangulateEdgeStripTerrain(
            triangulationData.middleEdgeVertices,
            _weights1,
            source.Index,
            triangulationData.centerEdgeVertices,
            _weights1,
            source.Index,
            hexOuterRadius,
            wrapSize,
            terrain
            );

        terrain.AddTrianglePerturbed(
            triangulationData.riverCenterLeft,
            triangulationData.middleEdgeVertices.vertex1,
            triangulationData.middleEdgeVertices.vertex2,
            hexOuterRadius,
            wrapSize
            );

        terrain.AddQuadPerturbed(
            triangulationData.riverCenterLeft,
            triangulationData.terrainCenter,
            triangulationData.middleEdgeVertices.vertex2,
            triangulationData.middleEdgeVertices.vertex3,
            hexOuterRadius,
            wrapSize
            );

        terrain.AddQuadPerturbed(
            triangulationData.terrainCenter,
            triangulationData.riverCenterRight,
            triangulationData.middleEdgeVertices.vertex3,
            triangulationData.middleEdgeVertices.vertex4,
            hexOuterRadius,
            wrapSize
            );

        terrain.AddTrianglePerturbed(
            triangulationData.riverCenterRight,
            triangulationData.middleEdgeVertices.vertex4,
            triangulationData.middleEdgeVertices.vertex5,
            hexOuterRadius,
            wrapSize
            );

        Vector3 centerHexIndices;

        centerHexIndices.x         =
            centerHexIndices.y     =
                centerHexIndices.z =
                    source.Index;

        terrain.AddTriangleHexData(
            centerHexIndices,
            _weights1
            );

        terrain.AddQuadHexData(
            centerHexIndices,
            _weights1
            );

        terrain.AddQuadHexData(
            centerHexIndices,
            _weights1
            );

        terrain.AddTriangleHexData(
            centerHexIndices,
            _weights1
            );

        return(triangulationData);
    }
コード例 #29
0
    public static FeatureContainer GetFeatureContainer(MapMeshChunkLayer walls) {
        GameObject resultObj = new GameObject("Feature Container");
        FeatureContainer resultMono = resultObj.AddComponent<FeatureContainer>();
        resultMono.urbanCollections = new FeatureCollection[3];
        resultMono.farmCollections = new FeatureCollection[3];
        resultMono.plantCollections = new FeatureCollection[3];
        resultMono.special = new Transform[3];
        resultMono.walls = walls;

        resultMono.wallTower = Resources.Load<Transform>("Wall Tower");
        resultMono.bridge = Resources.Load<Transform>("Bridge");
        
        resultMono.urbanCollections[0] = new FeatureCollection(
            new Transform[] {
                Resources.Load<Transform>("Urban High 1"),
                Resources.Load<Transform>("Urban High 2")
            }
        );

        resultMono.urbanCollections[1] = new FeatureCollection(
            new Transform[] {
                Resources.Load<Transform>("Urban Medium 1"),
                Resources.Load<Transform>("Urban Medium 2")
            }
        );

        resultMono.urbanCollections[2] = new FeatureCollection(
            new Transform[] {
                Resources.Load<Transform>("Urban Low 1"),
                Resources.Load<Transform>("Urban Low 2")
            }
        );

        resultMono.farmCollections[0] = new FeatureCollection(
            new Transform[] {
                Resources.Load<Transform>("Farm High 1"),
                Resources.Load<Transform>("Farm High 2")
            }
        );

        resultMono.farmCollections[1] = new FeatureCollection(
            new Transform[] {
                Resources.Load<Transform>("Farm Medium 1"),
                Resources.Load<Transform>("Farm Medium 2")
            }
        );

        resultMono.farmCollections[2] = new FeatureCollection(
            new Transform[] {
                Resources.Load<Transform>("Farm Low 1"),
                Resources.Load<Transform>("Farm Low 2")
            }
        );

        resultMono.plantCollections[0] = new FeatureCollection(
            new Transform[] {
                Resources.Load<Transform>("Plant High 1"),
                Resources.Load<Transform>("Plant High 2")
            }
        );

        resultMono.plantCollections[1] = new FeatureCollection(
            new Transform[] {
                Resources.Load<Transform>("Plant Medium 1"),
                Resources.Load<Transform>("Plant Medium 2")
            }
        );

        resultMono.plantCollections[2] = new FeatureCollection(
            new Transform[] {
                Resources.Load<Transform>("Plant Low 1"),
                Resources.Load<Transform>("Plant Low 2")
            }
        );

        resultMono.special[0] = Resources.Load<Transform>("Castle");
        resultMono.special[1] = Resources.Load<Transform>("Ziggurat");
        resultMono.special[2] = Resources.Load<Transform>("Megaflora");

        return resultMono;
    }
コード例 #30
0
    private TerrainTriangulationData TriangulateTerrainAdjacentToRiver(
        Hex source,
        HexDirections direction,
        TerrainTriangulationData triangulationData,
        Dictionary <HexDirections, bool> roadEdges,
        HexRiverData riverData,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer terrain,
        FeatureContainer features
        )
    {
        if (riverData.HasRiverInDirection(direction.NextClockwise()))
        {
/* If the direction has a river on either side, it has a slight curve.
 * The center vertex of river-adjacent triangle needs to be moved toward
 * the edge so they don't overlap the river.
 */
//            if (hex.HasRiverThroughEdge(direction.Previous())) {
            if (
                riverData.HasRiverInDirection(direction.PreviousClockwise())
                )
            {
                triangulationData.terrainCenter += HexagonPoint.GetSolidEdgeMiddle(
                    direction,
                    hexOuterRadius
                    ) * (HexagonConstants.INNER_TO_OUTER_RATIO * 0.5f);
            }

/* If the hex has a river through the previous previous direction,
 * it has a river flowing through the hex. Move the center vertex
 * of the river-adjacent triangle so that it does not overlap the river.
 */
            else if (
                riverData.HasRiverInDirection(
                    direction.PreviousClockwise2()
                    )
                )
            {
                triangulationData.terrainCenter +=
                    HexagonPoint.GetFirstSolidCorner(
                        direction,
                        hexOuterRadius
                        ) * 0.25f;
            }
        }

/* Second case of straight-river-adjacent triangle. Need to move center
 * so it doesn't overlap the river.
 */
        else if (
            riverData.HasRiverInDirection(direction.PreviousClockwise()) &&
            riverData.HasRiverInDirection(direction.NextClockwise2())
            )
        {
            triangulationData.terrainCenter += HexagonPoint.GetSecondSolidCorner(
                direction,
                hexOuterRadius
                ) * 0.25f;
        }

        EdgeVertices middle = new EdgeVertices(
            Vector3.Lerp(
                triangulationData.terrainCenter,
                triangulationData.centerEdgeVertices.vertex1,
                0.5f
                ),
            Vector3.Lerp(
                triangulationData.terrainCenter,
                triangulationData.centerEdgeVertices.vertex5,
                0.5f
                )
            );

        TriangulateEdgeStripTerrain(
            middle,
            _weights1,
            source.Index,
            triangulationData.centerEdgeVertices,
            _weights1,
            source.Index,
            hexOuterRadius,
            wrapSize,
            terrain
            );

        TriangulateEdgeFan(
            triangulationData.terrainCenter,
            middle,
            source.Index,
            hexOuterRadius,
            wrapSize,
            terrain
            );

        if (!source.IsUnderwater && roadEdges[direction])
        {
            features.AddFeature(
                source,
                (
                    triangulationData.terrainCenter +
                    triangulationData.centerEdgeVertices.vertex1 +
                    triangulationData.centerEdgeVertices.vertex5
                ) * (1f / 3f),
                hexOuterRadius,
                wrapSize
                );
        }

        return(triangulationData);
    }