private void TriangulateBoundaryTriangle(
            Vector3 begin, Color beginWeights,
            Vector3 left, Color leftWeights,
            Vector3 boundary, Color boundaryWeights, Vector3 indices
            )
        {
            Vector3 v2 = HexMetrics.Perturb(HexMetrics.TerraceLerp(begin, left, 1));
            Color   w2 = HexMetrics.TerraceLerp(beginWeights, leftWeights, 1);

            terrain.AddTriangleUnperturbed(HexMetrics.Perturb(begin), v2, boundary);
            terrain.AddTriangleCellData(indices, beginWeights, w2, boundaryWeights);

            for (int i = 2; i < HexMetrics.terraceSteps; i++)
            {
                Vector3 v1 = v2;
                Color   w1 = w2;
                v2 = HexMetrics.Perturb(HexMetrics.TerraceLerp(begin, left, i));
                w2 = HexMetrics.TerraceLerp(beginWeights, leftWeights, i);
                terrain.AddTriangleUnperturbed(v1, v2, boundary);
                terrain.AddTriangleCellData(indices, w1, w2, boundaryWeights);
            }

            terrain.AddTriangleUnperturbed(v2, HexMetrics.Perturb(left), boundary);
            terrain.AddTriangleCellData(indices, w2, leftWeights, boundaryWeights);
        }
예제 #2
0
        /// <summary>
        /// Handle corner triangle terraces(cliff-slop cases)
        /// </summary>
        /// <param name="begin">begin point of triangle</params>
        /// <param name="beginCell">begin hex cell</param>
        /// <param name="left">left point of triangle</param>
        /// <param name="leftCell">left hex cell</param>
        /// <param name="right">right point of triangle</param>
        /// <param name="rightCell">right hex cell</param>
        private void TriangulateCornerCliffTerraces(Vector3 begin, HexCell beginCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell)
        {
            float b = 1f / (leftCell.Elevation - beginCell.Elevation);

            if (b < 0)
            {
                b = -b;
            }
            Vector3 boundary        = Vector3.Lerp(HexMetrics.Perturb(begin), HexMetrics.Perturb(left), b);
            Color   boundaryWeights = Color.Lerp(weights1, weights2, b);
            Vector3 indices;

            indices.x = beginCell.Index;
            indices.y = leftCell.Index;
            indices.z = rightCell.Index;

            TriangulateBoundaryTriangle(right, weights3, begin, weights1, boundary, boundaryWeights, indices);

            if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope)
            {
                TriangulateBoundaryTriangle(left, weights2, right, weights3, boundary, boundaryWeights, indices);
            }
            else
            {
                terrain.AddTriangleUnperturbed(HexMetrics.Perturb(left), HexMetrics.Perturb(right), boundary);
                terrain.AddTriangleCellData(indices, weights2, weights3, boundaryWeights);
            }
        }
예제 #3
0
        public void AddSpecialFeature(HexCell cell, Vector3 position)
        {
            Transform instance = Instantiate(special[cell.SpecialIndex - 1]);

            instance.localPosition = HexMetrics.Perturb(position);
            HexHash hash = HexMetrics.SampleHashGrid(position);

            instance.localRotation = Quaternion.Euler(0f, 360f * hash.e, 0f);
            instance.SetParent(container, false);
        }
예제 #4
0
        public void AddTriangle(Vector3 v1, Vector3 v2, Vector3 v3)
        {
            int vertexIndex = vertices.Count;

            vertices.Add(HexMetrics.Perturb(v1));
            vertices.Add(HexMetrics.Perturb(v2));
            vertices.Add(HexMetrics.Perturb(v3));
            triangles.Add(vertexIndex);
            triangles.Add(vertexIndex + 1);
            triangles.Add(vertexIndex + 2);
        }
예제 #5
0
        public void AddBridge(Vector3 roadCenter1, Vector3 roadCenter2)
        {
            Transform instance = Instantiate(bridge);

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

            instance.localScale = new Vector3(1f, 1f, length * (1f / HexMetrics.bridgeDesignLength));
            instance.SetParent(container, false);
        }
예제 #6
0
        public void AddFeature(HexCell cell, Vector3 position)
        {
            if (cell.IsSpecial)
            {
                return;
            }
            HexHash   hash   = HexMetrics.SampleHashGrid(position);
            Transform prefab = PickPrefab(urbanCollections, cell.UrbanLevel, hash.a, hash.d);

            Transform otherPrefab = PickPrefab(farmCollections, cell.FarmLevel, hash.b, hash.d);
            float     usedHash    = hash.a;

            if (prefab)
            {
                if (otherPrefab && hash.b < hash.a)
                {
                    prefab   = otherPrefab;
                    usedHash = hash.b;
                }
            }
            else if (otherPrefab)
            {
                prefab   = otherPrefab;
                usedHash = hash.b;
            }

            otherPrefab = PickPrefab(plantCollections, cell.PlantLevel, hash.c, hash.d);
            if (prefab)
            {
                if (otherPrefab && hash.c < usedHash)
                {
                    prefab = otherPrefab;
                }
            }
            else if (otherPrefab)
            {
                prefab = otherPrefab;
            }
            else
            {
                return;
            }

            Transform instance = Instantiate(prefab);

            position.y            += instance.localScale.y * 0.5f;
            instance.localPosition = HexMetrics.Perturb(position);
            instance.localRotation = Quaternion.Euler(0f, 360f * hash.e, 0f);
            instance.SetParent(container, false);
        }
예제 #7
0
        private void AddWallCap(Vector3 near, Vector3 far)
        {
            near = HexMetrics.Perturb(near);
            far  = HexMetrics.Perturb(far);

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

            Vector3 v1, v2, v3, v4;

            v1   = v3 = center - thickness;
            v2   = v4 = center + thickness;
            v3.y = v4.y = center.y + HexMetrics.wallHeight;
            walls.AddQuadUnperturbed(v1, v2, v3, v4);
        }
예제 #8
0
        void TriangulateWaterfallInWater(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, float y1, float y2, float waterY)
        {
            v1.y = v2.y = y1;
            v3.y = v4.y = y2;
            v1   = HexMetrics.Perturb(v1);
            v2   = HexMetrics.Perturb(v2);
            v3   = HexMetrics.Perturb(v3);
            v4   = HexMetrics.Perturb(v4);
            float t = (waterY - y2) / (y1 - y2);

            v3 = Vector3.Lerp(v3, v1, t);
            v4 = Vector3.Lerp(v4, v2, t);
            rivers.AddQuadUnperturbed(v1, v2, v3, v4);
            rivers.AddQuadUV(0f, 1f, 0.8f, 1f);
        }
        void AddWallSegment(Vector3 nearLeft, Vector3 farLeft, Vector3 nearRight, Vector3 farRight, bool addTower = false)
        {
            nearLeft  = HexMetrics.Perturb(nearLeft);
            farLeft   = HexMetrics.Perturb(farLeft);
            nearRight = HexMetrics.Perturb(nearRight);
            farRight  = HexMetrics.Perturb(farRight);

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

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

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

            // One side
            Vector3 v1, v2, v3, v4;

            v1   = v3 = left - leftThicknessOffset;
            v2   = v4 = right - rightThicknessOffset;
            v3.y = leftTop;
            v4.y = rightTop;
            walls.AddQuadUnperturbed(v1, v2, v3, v4);

            Vector3 t1 = v3, t2 = v4;

            // The other side
            v1   = v3 = left + leftThicknessOffset;
            v2   = v4 = right + rightThicknessOffset;
            v3.y = leftTop;
            v4.y = rightTop;
            walls.AddQuadUnperturbed(v2, v1, v4, v3);

            // The top
            walls.AddQuadUnperturbed(t1, t2, v3, v4);

            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);
            }
        }
예제 #10
0
        private void AddWallWedge(Vector3 near, Vector3 far, Vector3 point)
        {
            near  = HexMetrics.Perturb(near);
            far   = HexMetrics.Perturb(far);
            point = HexMetrics.Perturb(point);

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

            Vector3 v1, v2, v3, v4;
            Vector3 pointTop = point;

            point.y = center.y;

            v1   = v3 = center - thickness;
            v2   = v4 = center + thickness;
            v3.y = v4.y = pointTop.y = center.y + HexMetrics.wallHeight;
            walls.AddQuadUnperturbed(v1, point, v3, pointTop);
            walls.AddQuadUnperturbed(point, v2, pointTop, v4);
            walls.AddTriangleUnperturbed(pointTop, v3, v4);
        }
예제 #11
0
        // Triangulate a corner with half terraces, half flat - Cliff on the left
        void TriangulateCornerCliffTerraces(Vector3 begin, HexCell beginCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell)
        {
            float b = 1f / (leftCell.Elevation - beginCell.Elevation);

            if (b < 0)
            {
                b = -b;
            }
            Vector3 boundary      = Vector3.Lerp(HexMetrics.Perturb(begin), HexMetrics.Perturb(left), b); // boundary is on a pertubed slope
            Color   boundaryColor = Color.Lerp(beginCell.Color, leftCell.Color, b);

            TriangulateBoundaryTriangle(right, rightCell, begin, beginCell, boundary, boundaryColor);

            if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope)
            {
                TriangulateBoundaryTriangle(left, leftCell, right, rightCell, boundary, boundaryColor);
            }
            else
            {
                terrain.AddTriangleUnpertubed(HexMetrics.Perturb(left), HexMetrics.Perturb(right), boundary);
                terrain.AddTriangleColor(leftCell.Color, rightCell.Color, boundaryColor);
            }
        }
예제 #12
0
        // Make a terrace in a corner, each terrace end in the boundary
        void TriangulateBoundaryTriangle(Vector3 begin, HexCell beginCell, Vector3 left, HexCell leftCell, Vector3 boundary, Color boundaryColor)
        {
            Vector3 v2 = HexMetrics.Perturb(HexMetrics.TerraceLerp(begin, left, 1));
            Color   c2 = HexMetrics.TerraceLerp(beginCell.Color, leftCell.Color, 1);

            // The first step is a triangle
            terrain.AddTriangleUnpertubed(HexMetrics.Perturb(begin), v2, boundary);
            terrain.AddTriangleColor(beginCell.Color, c2, boundaryColor);

            // All the steps are triangles
            for (int i = 2; i < HexMetrics.terraceSteps; i++)
            {
                Vector3 v1 = v2;
                Color   c1 = c2;
                v2 = HexMetrics.Perturb(HexMetrics.TerraceLerp(begin, left, i));
                c2 = HexMetrics.TerraceLerp(beginCell.Color, leftCell.Color, i);
                terrain.AddTriangleUnpertubed(v1, v2, boundary);
                terrain.AddTriangleColor(c1, c2, boundaryColor);
            }

            // The last step is a triangle
            terrain.AddTriangleUnpertubed(v2, HexMetrics.Perturb(left), boundary);
            terrain.AddTriangleColor(c2, leftCell.Color, boundaryColor);
        }