private void AddWallCap(
        Vector3 near,
        Vector3 far,
        float hexOuterRadius,
        int wrapSize
    ) {
        near = HexagonPoint.Perturb(
            near,
            hexOuterRadius,
            wrapSize
        );

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

        Vector3 center = HexagonPoint.WallLerp(near, far);
        Vector3 thickness = HexagonPoint.WallThicknessOffset(near, far);

        Vector3 vertex1;
        Vector3 vertex2;
        Vector3 vertex3;
        Vector3 vertex4;

        vertex1 = vertex3 = center - thickness;
        vertex2 = vertex4 = center + thickness;
        vertex3.y = vertex4.y = center.y + HexagonPoint.wallHeight;
        walls.AddQuadUnperturbed(vertex1, vertex2, vertex3, vertex4);
    }
    public void AddBridge(
        Vector3 roadCenter1,
        Vector3 roadCenter2,
        float hexOuterRadius,
        int wrapSize
    ) {
        roadCenter1 = HexagonPoint.Perturb(
            roadCenter1,
            hexOuterRadius,
            wrapSize
        );

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

        Transform instance = Instantiate(bridge);
        instance.localPosition = (roadCenter1 + roadCenter2) * 0.5f;
        instance.forward = roadCenter2 - roadCenter1;
        float length = Vector3.Distance(roadCenter1, roadCenter2);

        instance.localScale = 
        new Vector3
        (
            1f, 
            1f, 
            length * (1f / HexagonPoint.bridgeDesignLength)
        );

        instance.SetParent(_container, false);
    }
Beispiel #3
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);
    }
Beispiel #4
0
    /// <summary>
    /// Add a quad with perturbed corners.
    /// </summary>
    /// <param name="firstCorner">
    /// The first corner of the quad to be drawn, counter-clockwise.
    /// </param>
    /// <param name="secondCorner">
    /// The second corner of the quad to be drawn, counter-clockwise.
    /// </param>
    /// <param name="thirdCorner">
    /// The third corner of the quad to be drawn, counter-clockwise.
    /// </param>
    /// <param name="fourthCorner">
    /// The fourth corner of the quad to be drawn, counter-clockwise.
    /// </param>
    /// <param name="hexOuterRadius">
    /// The  outer radius (distance from the center to a given corner) of
    /// the hex which the quad is a part of.
    /// </param>
    /// <param name="wrapOffsetX">
    /// The offset required to wrap the map along the longitudinal axis.
    /// This should be equal to the longitudinal size of the plane which
    /// the hex being drawn is a part of.
    /// </param>
    public void AddQuadPerturbed(
        Vector3 firstCorner,
        Vector3 secondCorner,
        Vector3 thirdCorner,
        Vector3 fourthCorner,
        float hexOuterRadius,
        int wrapOffsetX
        )
    {
        int vertexIndex = _vertices.Count;

        _vertices.Add(
            HexagonPoint.Perturb(
                firstCorner,
                hexOuterRadius,
                wrapOffsetX
                )
            );

        _vertices.Add(
            HexagonPoint.Perturb(
                secondCorner,
                hexOuterRadius,
                wrapOffsetX
                )
            );

        _vertices.Add(
            HexagonPoint.Perturb(
                thirdCorner,
                hexOuterRadius,
                wrapOffsetX
                )
            );

        _vertices.Add(
            HexagonPoint.Perturb(
                fourthCorner,
                hexOuterRadius,
                wrapOffsetX
                )
            );

        _triangles.Add(vertexIndex);
        _triangles.Add(vertexIndex + 2);
        _triangles.Add(vertexIndex + 1);
        _triangles.Add(vertexIndex + 1);
        _triangles.Add(vertexIndex + 2);
        _triangles.Add(vertexIndex + 3);
    }
    private void AddWallWedge(
        Vector3 near,
        Vector3 far,
        Vector3 point,
        float hexOuterRadius,
        int wrapSize
    ) {
        near = HexagonPoint.Perturb(
            near,
            hexOuterRadius,
            wrapSize
        );

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

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

        Vector3 center = HexagonPoint.WallLerp(near, far);
        Vector3 thickness = HexagonPoint.WallThicknessOffset(near, far);

        Vector3 vertex1;
        Vector3 vertex2;
        Vector3 vertex3;
        Vector3 vertex4;

        Vector3 pointTop = point;
        point.y = center.y;

        vertex1 = vertex3 = center - thickness;
        vertex2 = vertex4 = center + thickness;
        vertex3.y = vertex4.y = pointTop.y = center.y + HexagonPoint.wallHeight;
        
        walls.AddQuadUnperturbed(vertex1, point, vertex3, pointTop);
        walls.AddQuadUnperturbed(point, vertex2, pointTop, vertex4);
        walls.AddTriangleUnperturbed(pointTop, vertex3, vertex4);
    }
    public void AddSpecialFeature(
        Hex hex,
        Vector3 position,
        float hexOuterRadius,
        int wrapSize
    ) {
        Transform instance = Instantiate(special[hex.SpecialIndex - 1]);

        instance.localPosition = HexagonPoint.Perturb(
            position,
            hexOuterRadius,
            wrapSize
        );

        RandomHash rootHash = HexagonPoint.SampleHashGrid(position);
        float e = rootHash.GetValue(4);

        instance.localRotation = Quaternion.Euler(0f, 360f * e, 0f);
        instance.SetParent(_container, false);
    }
    private void AddWallSegment(
        Vector3 nearLeft,
        Vector3 farLeft,
        Vector3 nearRight,
        Vector3 farRight,
        float hexOuterRadius,
        int wrapSize,
        bool addTower = false
    ) {
        nearLeft = HexagonPoint.Perturb(
            nearLeft,
            hexOuterRadius,
            wrapSize
        );
        
        farLeft = HexagonPoint.Perturb(
            farLeft,
            hexOuterRadius,
            wrapSize
        );
        
        nearRight = HexagonPoint.Perturb(
            nearRight,
            hexOuterRadius,
            wrapSize
        );
        
        farRight = HexagonPoint.Perturb(
            farRight,
            hexOuterRadius,
            wrapSize
        );

        Vector3 left = HexagonPoint.WallLerp(nearLeft, farLeft);
        Vector3 right = HexagonPoint.WallLerp(nearRight, farRight);

        Vector3 leftThicknessOffset = 
            HexagonPoint.WallThicknessOffset(nearLeft, farLeft);
        Vector3 rightThicknessOffset = 
            HexagonPoint.WallThicknessOffset(nearRight, farRight);

        float leftTop = left.y + HexagonPoint.wallHeight;
        float rightTop = right.y + HexagonPoint.wallHeight;

        Vector3 vertex1;
        Vector3 vertex2;
        Vector3 vertex3;
        Vector3 vertex4;

        vertex1 = vertex3 = left - leftThicknessOffset;
        vertex2 = vertex4 = right - rightThicknessOffset;
        vertex3.y = leftTop;
        vertex4.y = rightTop;
        walls.AddQuadUnperturbed(vertex1, vertex2, vertex3, vertex4);

        Vector3 top1 = vertex3;
        Vector3 top2 = vertex4;

        vertex1 = vertex3 = left + leftThicknessOffset;
        vertex2 = vertex4 = right + rightThicknessOffset;
        vertex3.y = leftTop;
        vertex4.y = rightTop;
        walls.AddQuadUnperturbed(vertex2, vertex1, vertex4, vertex3);

        walls.AddQuadUnperturbed(top1, top2, vertex3, vertex4);

        if (addTower) {
            Transform towerInstance = Instantiate(wallTower);
            towerInstance.transform.localPosition = (left + right) * 0.5f;
            Vector3 rightDirection = right - left;
            rightDirection.y = 0f;
            towerInstance.transform.right = rightDirection;
            towerInstance.SetParent(_container, false);
        }
    }
    public void AddFeature(
        Hex hex,
        Vector3 position,
        float hexOuterRadius,
        int wrapSize
    ) {

        if (hex.IsSpecial) {
            return;
        }

/* Randomness of rotation is obtained by sampling a Hash
* World rather than using Random, so the rotation of objects
* will not be changed when the hex is refreshed.
*/

        RandomHash randomHash = HexagonPoint.SampleHashGrid(position);
        float a = randomHash.GetValue(0);
        float b = randomHash.GetValue(1);
        float c = randomHash.GetValue(2);
        float d = randomHash.GetValue(3);
        float e = randomHash.GetValue(4);

        Transform prefab = PickPrefab(
            urbanCollections, hex.UrbanLevel, a, d
        );

        Transform otherPrefab = PickPrefab(
            farmCollections, hex.FarmLevel, b, d
        );

        float usedHash = randomHash.GetValue(0);
        if (prefab) {
            if (otherPrefab && b < a) {
                prefab = otherPrefab;
                usedHash = b;
            }
        }
        else if (otherPrefab) {
            prefab = otherPrefab;
            usedHash = b;
        }

        otherPrefab = PickPrefab (
            plantCollections, hex.PlantLevel, c, d
        );

        if (prefab) {
            if (otherPrefab && c < usedHash) {
                prefab = otherPrefab;
            }
        }
        else if (otherPrefab) {
            prefab = otherPrefab;
        }
        else {
            return;
        }

        if (!prefab) {
            return;
        }

        Transform instance = Instantiate(prefab);

        instance.localPosition = HexagonPoint.Perturb(
            position,
            hexOuterRadius,
            wrapSize
        );
        
        instance.localRotation = Quaternion.Euler(0f, 360f * e, 0f);

        instance.SetParent(_container, false);
    }
Beispiel #9
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);
    }
Beispiel #10
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
                );
        }
    }