コード例 #1
0
        private void RenderSpline(BezierSpline spline, IHexMesh mesh)
        {
            if (spline == null)
            {
                return;
            }

            float delta = 1f / RenderConfig.RoadQuadsPerCurve;

            float v1, v2 = 0;

            Vector3 lowerLeft, lowerRight, upperLeft, upperRight;

            for (float t = 0f; t < 1f; t += delta)
            {
                lowerLeft  = spline.GetPoint(t) + spline.GetNormalXZ(t).normalized *RenderConfig.RoadWidth / 2f;
                lowerRight = spline.GetPoint(t) - spline.GetNormalXZ(t).normalized *RenderConfig.RoadWidth / 2f;

                upperLeft  = spline.GetPoint(t + delta) + spline.GetNormalXZ(t + delta).normalized *RenderConfig.RoadWidth / 2f;
                upperRight = spline.GetPoint(t + delta) - spline.GetNormalXZ(t + delta).normalized *RenderConfig.RoadWidth / 2f;

                v1 = v2;

                v2 += (lowerLeft - lowerRight).magnitude / RenderConfig.RoadVRepeatLength;

                mesh.AddQuad(lowerLeft, lowerRight, upperLeft, upperRight);
                mesh.AddQuadUV(0f, 1f, v1, v2);
            }
        }
コード例 #2
0
        public void TriangulateRoads(IHexCell cell, IHexMesh roadsMesh)
        {
            if (cell.HasRoads)
            {
                var cellHash = NoiseGenerator.SampleHashGrid(cell.AbsolutePositionXZ);

                var directionsWithRoad = EnumUtil.GetValues <HexDirection>().Where(
                    direction => Grid.HasNeighbor(cell, direction) && Grid.GetNeighbor(cell, direction).HasRoads
                    ).ToList();

                while (directionsWithRoad.Any())
                {
                    var startDirection = directionsWithRoad.First();

                    directionsWithRoad.Remove(startDirection);

                    BezierSpline spline;

                    if (directionsWithRoad.Any())
                    {
                        var endDirection = GetBestDirection(startDirection, directionsWithRoad, cellHash);

                        directionsWithRoad.Remove(endDirection);

                        spline = BuildSplineBetween(cell, startDirection, endDirection);
                    }
                    else
                    {
                        spline = BuildSplineToCenter(cell, startDirection);
                    }

                    RenderSpline(spline, roadsMesh);
                }
            }
        }
コード例 #3
0
        private void TriangulateCultureAlongContour(
            IHexCell center, HexDirection direction, Color color, IHexMesh cultureMesh
            )
        {
            var contour = CellEdgeContourCanon.GetContourForCellEdge(center, direction);

            Vector2 innerCCW, innerCW, outerCCW, outerCW;

            for (int i = 0; i < contour.Count - 1; i++)
            {
                outerCCW = contour[i];
                outerCW  = contour[i + 1];

                innerCCW = Vector2.Lerp(outerCCW, center.AbsolutePositionXZ, RenderConfig.CultureWidthPercent);
                innerCW  = Vector2.Lerp(outerCW, center.AbsolutePositionXZ, RenderConfig.CultureWidthPercent);

                cultureMesh.AddQuad(
                    new Vector3(innerCCW.x, 0f, innerCCW.y), new Vector3(innerCW.x, 0f, innerCW.y),
                    new Vector3(outerCCW.x, 0f, outerCCW.y), new Vector3(outerCW.x, 0f, outerCW.y)
                    );

                cultureMesh.AddQuadUV(new Vector2(0f, 0f), new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(0f, 1f));

                cultureMesh.AddQuadColor(color);
            }
        }
コード例 #4
0
        private void TriangulateMarshCenter(IHexCell center, HexDirection direction, IHexMesh mesh)
        {
            mesh.AddTriangle(
                center.AbsolutePosition,
                center.AbsolutePosition + RenderConfig.GetFirstSolidCorner(direction),
                center.AbsolutePosition + RenderConfig.GetSecondSolidCorner(direction)
                );

            mesh.AddTriangleUV(Vector2.one, Vector2.one, Vector2.one);
        }
コード例 #5
0
        public void Destroy(IHexMesh mesh)
        {
            allMeshes.Remove(mesh);

            var concreteMesh = mesh as HexMesh;

            if (concreteMesh != null)
            {
                HexMeshPool.Despawn(concreteMesh);
            }
        }
コード例 #6
0
        private void TriangulateWaterCenter(
            IHexCell center, IHexMesh mesh, HexDirection direction, Vector3 localCell, Color centerColor
            )
        {
            mesh.AddTriangle(
                localCell,
                localCell + RenderConfig.GetFirstSolidCorner(direction),
                localCell + RenderConfig.GetSecondSolidCorner(direction)
                );

            mesh.AddTriangleColor(centerColor);
        }
コード例 #7
0
        private void TriangulateMarshCorner(
            IHexCell center, IHexCell left, IHexCell right, float centerV, float leftV, float rightV,
            HexDirection direction, IHexMesh mesh
            )
        {
            Vector3 centerPoint = center.AbsolutePosition + RenderConfig.GetFirstSolidCorner(direction);
            Vector3 leftPoint   = left.AbsolutePosition + RenderConfig.GetFirstSolidCorner(direction.Next2());
            Vector3 rightPoint  = right.AbsolutePosition + RenderConfig.GetFirstSolidCorner(direction.Previous2());

            mesh.AddTriangle(centerPoint, leftPoint, rightPoint);
            mesh.AddTriangleUV(new Vector2(0f, centerV), new Vector2(0f, leftV), new Vector2(0f, rightV));
        }
コード例 #8
0
        public void TrianglateOasis(IHexCell cell, IHexMesh waterMesh, IHexMesh landMesh)
        {
            if (cell.Feature != CellFeature.Oasis)
            {
                return;
            }

            float waterDistance = RenderConfig.OasisWaterRadius;
            float landDistance  = RenderConfig.OasisWaterRadius + RenderConfig.OasisLandWidth;

            float tDelta = 2 * Mathf.PI / RenderConfig.OasisBoundarySegments;

            Vector3 perturbedCenter = NoiseGenerator.Perturb(cell.AbsolutePosition);

            Vector3 waterTwo = NoiseGenerator.Perturb(
                cell.AbsolutePosition + new Vector3(waterDistance, 0f, 0f)
                );

            Vector3 landTwo = NoiseGenerator.Perturb(
                cell.AbsolutePosition + new Vector3(landDistance, 0f, 0f)
                );

            for (float t = 0f; t < 2 * Mathf.PI; t += tDelta)
            {
                Vector3 waterOne = waterTwo;
                Vector3 landOne  = landTwo;

                waterTwo = NoiseGenerator.Perturb(
                    cell.AbsolutePosition + new Vector3(waterDistance * Mathf.Cos(t), 0f, waterDistance * Mathf.Sin(t))
                    );

                landTwo = NoiseGenerator.Perturb(
                    cell.AbsolutePosition + new Vector3(landDistance * Mathf.Cos(t), 0f, landDistance * Mathf.Sin(t))
                    );

                waterMesh.AddTriangle(perturbedCenter, waterTwo, waterOne);

                waterMesh.AddTriangleUV(Vector2.one, Vector2.one, Vector2.one);

                landMesh.AddQuad(waterTwo, waterOne, landTwo, landOne);
            }

            waterMesh.AddTriangle(
                perturbedCenter, NoiseGenerator.Perturb(cell.AbsolutePosition + new Vector3(waterDistance, 0f, 0f)), waterTwo
                );

            landMesh.AddQuad(
                NoiseGenerator.Perturb(cell.AbsolutePosition + new Vector3(waterDistance, 0f, 0f)), waterTwo,
                NoiseGenerator.Perturb(cell.AbsolutePosition + new Vector3(landDistance, 0f, 0f)), landTwo
                );

            waterMesh.AddTriangleUV(Vector2.one, Vector2.one, Vector2.one);
        }
コード例 #9
0
        private void ClearHexMeshes()
        {
            if (standingWater != null)
            {
                standingWater.Clear();
                HexMeshFactory.Destroy(standingWater);

                standingWater = null;
            }

            if (culture != null)
            {
                culture.Clear();
                HexMeshFactory.Destroy(culture);

                culture = null;
            }

            if (roads != null)
            {
                roads.Clear();
                HexMeshFactory.Destroy(roads);

                roads = null;
            }

            if (marshWater != null)
            {
                marshWater.Clear();
                HexMeshFactory.Destroy(marshWater);

                marshWater = null;
            }

            if (oasisWater != null)
            {
                oasisWater.Clear();
                HexMeshFactory.Destroy(oasisWater);

                oasisWater = null;
            }

            if (oasisLand != null)
            {
                oasisLand.Clear();
                HexMeshFactory.Destroy(oasisLand);

                oasisLand = null;
            }
        }
コード例 #10
0
        private void TriangulateWaterEdge(
            IHexCell center, Vector3 localCenterPos, Color centerColor,
            IHexCell right, Vector3 localRightPos, Color rightColor,
            HexDirection direction, IHexMesh mesh
            )
        {
            mesh.AddQuad(
                localCenterPos + RenderConfig.GetFirstSolidCorner(direction),
                localCenterPos + RenderConfig.GetSecondSolidCorner(direction),
                localRightPos + RenderConfig.GetSecondSolidCorner(direction.Opposite()),
                localRightPos + RenderConfig.GetFirstSolidCorner(direction.Opposite())
                );

            mesh.AddQuadColor(centerColor, rightColor);
        }
コード例 #11
0
        private void TriangulateWaterCorner(
            IHexCell center, Vector3 localCenterPos, Color centerColor,
            IHexCell right, Vector3 localRightPos, Color rightColor,
            IHexCell left, Vector3 localLeftPos, Color leftColor,
            HexDirection direction, IHexMesh mesh
            )
        {
            mesh.AddTriangle(
                localCenterPos + RenderConfig.GetFirstSolidCorner(direction),
                localLeftPos + RenderConfig.GetFirstSolidCorner(direction.Next2()),
                localRightPos + RenderConfig.GetFirstSolidCorner(direction.Previous2())
                );

            mesh.AddTriangleColor(centerColor, leftColor, rightColor);
        }
コード例 #12
0
        public void TriangulateMarshes(IHexCell center, IHexMesh mesh)
        {
            foreach (var direction in EnumUtil.GetValues <HexDirection>())
            {
                if (center.Vegetation == CellVegetation.Marsh)
                {
                    TriangulateMarshCenter(center, direction, mesh);
                }

                if (direction > HexDirection.SE)
                {
                    continue;
                }

                IHexCell right = Grid.GetNeighbor(center, direction);
                IHexCell left  = Grid.GetNeighbor(center, direction.Previous());

                if (right == null)
                {
                    continue;
                }

                float centerV = center.Vegetation == CellVegetation.Marsh ? 1f : 0f;
                float leftV   = left != null && left.Vegetation == CellVegetation.Marsh ? 1f : 0f;
                float rightV  = right != null && right.Vegetation == CellVegetation.Marsh ? 1f : 0f;

                if (centerV != 0f || rightV != 0f)
                {
                    TriangulateMarshEdge(center, right, centerV, rightV, direction, mesh);
                }

                if (direction > HexDirection.E)
                {
                    continue;
                }

                if (left == null)
                {
                    continue;
                }

                if (centerV != 0f || leftV != 0f || rightV != 0f)
                {
                    TriangulateMarshCorner(center, left, right, centerV, leftV, rightV, direction, mesh);
                }
            }
        }
コード例 #13
0
        public void TriangulateCellWeights(IHexCell center, IHexMesh weightsMesh)
        {
            foreach (var direction in EnumUtil.GetValues <HexDirection>())
            {
                bool hasCenterRightRiver = RiverCanon.HasRiverAlongEdge(center, direction);

                IHexCell right = Grid.GetNeighbor(center, direction);

                if (hasCenterRightRiver)
                {
                    TriangulateCellWeights_River(center, right, direction, hasCenterRightRiver, weightsMesh);
                }
                else
                {
                    TriangulateCellWeights_NoRiver(center, right, direction, weightsMesh);
                }
            }
        }
コード例 #14
0
        public void TriangulateCultureInDirection(
            IHexCell center, HexDirection direction, IHexMesh cultureMesh
            )
        {
            var centerOwner = CivTerritoryLogic.GetCivClaimingCell(center);

            if (centerOwner == null)
            {
                return;
            }

            IHexCell left      = Grid.GetNeighbor(center, direction.Previous());
            IHexCell right     = Grid.GetNeighbor(center, direction);
            IHexCell nextRight = Grid.GetNeighbor(center, direction.Next());

            if (right == null)
            {
                return;
            }

            if (CivTerritoryLogic.GetCivClaimingCell(right) != centerOwner)
            {
                TriangulateCultureAlongContour(center, direction, centerOwner.Template.Color, cultureMesh);
            }
            else
            {
                var centerRightContour = CellEdgeContourCanon.GetContourForCellEdge(center, direction);
                var rightCenterContour = CellEdgeContourCanon.GetContourForCellEdge(right, direction.Opposite());

                if (rightCenterContour.Count <= 3)
                {
                    TriangulateCultureCorners_FlatEdge(
                        center, left, right, nextRight, direction, centerOwner, centerRightContour, rightCenterContour, cultureMesh
                        );
                }
                else
                {
                    TriangulateCultureCorners_River(
                        center, left, right, nextRight, direction, centerOwner, centerRightContour, cultureMesh
                        );
                }
            }
        }
コード例 #15
0
        public void Clear()
        {
            if (cells == null || cells.Count == 0)
            {
                return;
            }

            CellSignals.MapBeingClearedSignal.OnNext(new UniRx.Unit());

            cells.Clear();

            foreach (var chunk in chunks)
            {
                MapChunkPool.Despawn(chunk);
            }

            chunks     = null;
            castChunks = null;

            if (RiverSurfaceMesh != null)
            {
                HexMeshFactory.Destroy(RiverSurfaceMesh);
            }
            if (RiverBankMesh != null)
            {
                HexMeshFactory.Destroy(RiverBankMesh);
            }
            if (RiverDuckMesh != null)
            {
                HexMeshFactory.Destroy(RiverDuckMesh);
            }
            if (FarmMesh != null)
            {
                HexMeshFactory.Destroy(FarmMesh);
            }

            RiverSurfaceMesh = null;
            RiverBankMesh    = null;
            RiverDuckMesh    = null;
            FarmMesh         = null;
        }
コード例 #16
0
        private void TriangulateCellWeights_NoRiver(
            IHexCell center, IHexCell right, HexDirection direction, IHexMesh weightsMesh
            )
        {
            if (right == null)
            {
                weightsMesh.AddTriangle(
                    center.AbsolutePosition,
                    center.AbsolutePosition + RenderConfig.GetFirstCorner(direction),
                    center.AbsolutePosition + RenderConfig.GetSecondCorner(direction)
                    );
                weightsMesh.AddTriangleColor(CenterWeights);

                return;
            }

            Vector3 firstEdgeInner  = center.AbsolutePosition + RenderConfig.GetFirstSolidCorner(direction);
            Vector3 secondEdgeInner = center.AbsolutePosition + RenderConfig.GetSecondSolidCorner(direction);

            //Solid center region
            weightsMesh.AddTriangle(center.AbsolutePosition, firstEdgeInner, secondEdgeInner);
            weightsMesh.AddTriangleColor(CenterWeights);

            Vector3 firstEdgeOuter  = (firstEdgeInner + right.AbsolutePosition + RenderConfig.GetSecondSolidCorner(direction.Opposite())) / 2f;
            Vector3 secondEdgeOuter = (secondEdgeInner + right.AbsolutePosition + RenderConfig.GetFirstSolidCorner(direction.Opposite())) / 2f;

            //The edge between Center and Right, going up to the dividing line
            weightsMesh.AddQuad(firstEdgeInner, secondEdgeInner, firstEdgeOuter, secondEdgeOuter);
            weightsMesh.AddQuadColor(CenterWeights, CenterRightWeights);

            //Previous corner out to the edge of the cell
            weightsMesh.AddTriangle(firstEdgeInner, center.AbsolutePosition + RenderConfig.GetFirstCorner(direction), firstEdgeOuter);
            weightsMesh.AddTriangleColor(CenterWeights, CenterLeftRightWeights, CenterRightWeights);

            //Next corner out to the edge of the cell
            weightsMesh.AddTriangle(secondEdgeInner, secondEdgeOuter, center.AbsolutePosition + RenderConfig.GetSecondCorner(direction));
            weightsMesh.AddTriangleColor(CenterWeights, CenterRightWeights, CenterRightNextRightWeights);
        }
コード例 #17
0
        public void Build(int cellCountX, int cellCountZ)
        {
            RiverSurfaceMesh = HexMeshFactory.Create("River Surfaces", RenderConfig.RiverSurfaceData);
            RiverBankMesh    = HexMeshFactory.Create("River Banks", RenderConfig.RiverBankData);
            RiverDuckMesh    = HexMeshFactory.Create("River Ducking", RenderConfig.RiverDuckData);
            FarmMesh         = HexMeshFactory.Create("Farmland", RenderConfig.FarmlandData);

            RiverSurfaceMesh.transform.SetParent(transform, false);
            RiverBankMesh.transform.SetParent(transform, false);
            RiverDuckMesh.transform.SetParent(transform, false);
            FarmMesh.transform.SetParent(transform, false);

            Clear();

            CellCountX = cellCountX;
            CellCountZ = cellCountZ;

            ShaderData.Initialize(CellCountX, CellCountZ);

            CreateCells();
            CreateChunks();
            AttachChunksToCells();
        }
コード例 #18
0
        public void TriangulateOrientation(IHexCell center, IHexMesh orientationMesh)
        {
            short indexOffset = (short)(center.Index + 1);

            foreach (var direction in EnumUtil.GetValues <HexDirection>())
            {
                byte[] rg = BitConverter.GetBytes(indexOffset);
                byte   b  = (byte)direction;

                var cellColor = new Color32(rg[0], rg[1], b, 0);

                var centerContour = CellContourCanon.GetContourForCellEdge(center, direction);

                for (int i = 1; i < centerContour.Count; i++)
                {
                    orientationMesh.AddTriangle(
                        center.AbsolutePosition, centerContour[i - 1].ToXYZ(), centerContour[i].ToXYZ()
                        );

                    orientationMesh.AddTriangleColor(cellColor);
                }

                if (direction <= HexDirection.SE && RiverCanon.HasRiverAlongEdge(center, direction))
                {
                    var right = Grid.GetNeighbor(center, direction);

                    ContourTriangulator.TriangulateContoursBetween(
                        center, right, direction, cellColor, cellColor, orientationMesh
                        );

                    if (direction <= HexDirection.E && RiverCanon.HasRiverAlongEdge(right, direction.Previous2()))
                    {
                    }
                }
            }
        }
コード例 #19
0
        //Center should always be a water cell of some variety.
        //We need to extend water borders into land cells to make
        //sure the water goes all the way up to the shore.
        public void TriangulateWaterForCell(IHexCell center, Transform localTransform, IHexMesh mesh)
        {
            Vector3 localCenterPos = localTransform.InverseTransformPoint(center.AbsolutePosition);

            localCenterPos.y = RenderConfig.WaterY;

            foreach (var direction in EnumUtil.GetValues <HexDirection>())
            {
                Color centerColor, leftColor, rightColor;

                GetWaterColors(center, direction, out centerColor, out leftColor, out rightColor);


                TriangulateWaterCenter(center, mesh, direction, localCenterPos, centerColor);


                var right = Grid.GetNeighbor(center, direction);

                if (right == null || (right.Terrain.IsWater() && direction > HexDirection.SE))
                {
                    continue;
                }

                Vector3 localRightPos = localTransform.InverseTransformPoint(right.AbsolutePosition);
                localRightPos.y = RenderConfig.WaterY;

                if (center.Terrain.IsWater())
                {
                    TriangulateWaterEdge(
                        center, localCenterPos, centerColor, right, localRightPos, rightColor,
                        direction, mesh
                        );
                }
                else if (right.Terrain.IsWater())
                {
                    TriangulateWaterEdge(
                        right, localRightPos, rightColor, center, localCenterPos, centerColor,
                        direction.Opposite(), mesh
                        );
                }


                var left = Grid.GetNeighbor(center, direction.Previous());

                //We can't use the normal paradigm for corners because
                //we aren't triangulating from every cell. We need to
                //triangulate every land corner, and then exclude water
                //corners, which this check does.
                if (left == null ||
                    (right.Terrain.IsWater() && direction > HexDirection.E) ||
                    (left.Terrain.IsWater() && direction > HexDirection.SW)
                    )
                {
                    continue;
                }

                Vector3 localLeftPos = localTransform.InverseTransformPoint(left.AbsolutePosition);
                localLeftPos.y = RenderConfig.WaterY;

                TriangulateWaterCorner(
                    center, localCenterPos, centerColor,
                    right, localRightPos, rightColor,
                    left, localLeftPos, leftColor,
                    direction, mesh
                    );
            }
        }
コード例 #20
0
        private void TriangulateCultureCorners_FlatEdge(
            IHexCell center, IHexCell left, IHexCell right, IHexCell nextRight, HexDirection direction,
            ICivilization centerOwner, ReadOnlyCollection <Vector2> centerRightContour,
            ReadOnlyCollection <Vector2> rightCenterContour, IHexMesh cultureMesh
            )
        {
            if (left != null && CivTerritoryLogic.GetCivClaimingCell(left) != centerOwner)
            {
                Color cultureColor = centerOwner.Template.Color;

                var centerLeftContour = CellEdgeContourCanon.GetContourForCellEdge(center, direction.Previous());
                var rightLeftContour  = CellEdgeContourCanon.GetContourForCellEdge(right, direction.Previous2());

                Vector2 centerLeftFirstInner = Vector2.Lerp(centerLeftContour.First(), center.AbsolutePositionXZ, RenderConfig.CultureWidthPercent);
                Vector2 centerLeftLastInner  = Vector2.Lerp(centerLeftContour.Last(), center.AbsolutePositionXZ, RenderConfig.CultureWidthPercent);

                Vector2 rightLeftFirstInner = Vector2.Lerp(rightLeftContour.First(), right.AbsolutePositionXZ, RenderConfig.CultureWidthPercent);
                Vector2 rightleftLastInner  = Vector2.Lerp(rightLeftContour.Last(), right.AbsolutePositionXZ, RenderConfig.CultureWidthPercent);

                Vector2 rayAlongCenterLeft = (centerLeftLastInner - centerLeftFirstInner).normalized;
                Vector2 rayAlongRightLeft  = (rightLeftFirstInner - rightleftLastInner).normalized;

                Vector2 bezierControl;

                if (!Geometry2D.ClosestPointsOnTwoLines(
                        centerLeftLastInner, rayAlongCenterLeft, rightLeftFirstInner, rayAlongRightLeft,
                        out bezierControl, out bezierControl
                        ))
                {
                    Debug.LogError("TriangulateCultureCorners_FlatEdge failed to find a valid control point");
                    return;
                }


                Vector3 pivotXYZ = new Vector3(centerLeftContour.Last().x, 0f, centerLeftContour.Last().y);

                float paramDelta = 5f / RenderConfig.RiverQuadsPerCurve;

                for (float t = 0; t < 1f; t = Mathf.Clamp01(t + paramDelta))
                {
                    float nextT = Mathf.Clamp01(t + paramDelta);

                    Vector2 bezierOne = BezierQuadratic.GetPoint(centerLeftLastInner, bezierControl, rightLeftFirstInner, nextT);
                    Vector2 bezierTwo = BezierQuadratic.GetPoint(centerLeftLastInner, bezierControl, rightLeftFirstInner, t);

                    cultureMesh.AddTriangle(pivotXYZ, new Vector3(bezierOne.x, 0f, bezierOne.y), new Vector3(bezierTwo.x, 0f, bezierTwo.y));

                    cultureMesh.AddTriangleUV(new Vector2(0f, 1f), Vector2.zero, Vector2.zero);

                    cultureMesh.AddTriangleColor(cultureColor);
                }

                if (rightCenterContour.Count == 3)
                {
                    Vector2 innerPoint          = Vector2.Lerp(rightCenterContour.Last(), right.AbsolutePositionXZ, RenderConfig.CultureWidthPercent);
                    Vector2 secondToLastContour = rightCenterContour[rightCenterContour.Count - 2];
                    Vector2 lastContour         = rightCenterContour.Last();

                    cultureMesh.AddTriangle(
                        new Vector3(innerPoint.x, 0f, innerPoint.y), new Vector3(secondToLastContour.x, 0f, secondToLastContour.y),
                        new Vector3(lastContour.x, 0f, lastContour.y)
                        );

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

                    cultureMesh.AddTriangleColor(cultureColor);
                }
            }
        }
コード例 #21
0
        private void TriangulateCellWeights_River(
            IHexCell center, IHexCell right, HexDirection direction, bool hasCenterRightRiver, IHexMesh weightsMesh
            )
        {
            var centerRightContour = CellContourCanon.GetContourForCellEdge(center, direction);

            Vector3 innerOne, innerTwo, contourOneXYZ, contourTwoXYZ;

            for (int i = 1; i < centerRightContour.Count; i++)
            {
                contourOneXYZ = centerRightContour[i - 1].ToXYZ();
                contourTwoXYZ = centerRightContour[i].ToXYZ();

                innerOne = Vector3.Lerp(center.AbsolutePosition, contourOneXYZ, RenderConfig.SolidFactor);
                innerTwo = Vector3.Lerp(center.AbsolutePosition, contourTwoXYZ, RenderConfig.SolidFactor);

                weightsMesh.AddTriangle(center.AbsolutePosition, innerOne, innerTwo);
                weightsMesh.AddTriangleColor(CenterWeights);

                weightsMesh.AddQuad(innerOne, innerTwo, contourOneXYZ, contourTwoXYZ);

                if (hasCenterRightRiver)
                {
                    weightsMesh.AddQuadColor(CenterWeights);
                }
                else
                {
                    weightsMesh.AddQuadColor(CenterWeights, CenterRightWeights);
                }
            }

            if (hasCenterRightRiver && direction <= HexDirection.SE)
            {
                ContourTriangulator.TriangulateContoursBetween(
                    center, right, direction, CenterWeights, RightWeights, weightsMesh
                    );
            }
        }
コード例 #22
0
        public void TriangulateContoursBetween(
            IHexCell center, IHexCell right, HexDirection direction, Color centerWeights, Color rightWeights, IHexMesh mesh
            )
        {
            var centerRightContour = CellContourCanon.GetContourForCellEdge(center, direction);
            var rightCenterContour = CellContourCanon.GetContourForCellEdge(right, direction.Opposite());

            int centerRightIndex = 1, rightCenterIndex = rightCenterContour.Count - 1;

            while (centerRightIndex < centerRightContour.Count && rightCenterIndex > 0)
            {
                mesh.AddQuad(
                    centerRightContour[centerRightIndex - 1].ToXYZ(), centerRightContour[centerRightIndex].ToXYZ(),
                    rightCenterContour[rightCenterIndex].ToXYZ(), rightCenterContour[rightCenterIndex - 1].ToXYZ()
                    );

                mesh.AddQuadColor(centerWeights, rightWeights);

                centerRightIndex++;
                rightCenterIndex--;
            }

            for (; centerRightIndex < centerRightContour.Count; centerRightIndex++)
            {
                mesh.AddTriangle(
                    centerRightContour[centerRightIndex - 1].ToXYZ(), rightCenterContour[0].ToXYZ(), centerRightContour[centerRightIndex].ToXYZ()
                    );

                mesh.AddTriangleColor(centerWeights, rightWeights, centerWeights);
            }

            for (; rightCenterIndex > 0; rightCenterIndex--)
            {
                mesh.AddTriangle(
                    centerRightContour.Last().ToXYZ(), rightCenterContour[rightCenterIndex].ToXYZ(), rightCenterContour[rightCenterIndex - 1].ToXYZ()
                    );

                mesh.AddTriangleColor(centerWeights, rightWeights, rightWeights);
            }

            if (RiverCanon.HasRiverAlongEdge(right, direction.Next2()))
            {
                var nextRight = Grid.GetNeighbor(center, direction.Next());

                var rightNextRightContour = CellContourCanon.GetContourForCellEdge(right, direction.Next2());
                var nextRightRightContour = CellContourCanon.GetContourForCellEdge(nextRight, direction.Previous());

                mesh.AddTriangle(
                    centerRightContour.Last().ToXYZ(),
                    rightNextRightContour.Last().ToXYZ(),
                    nextRightRightContour.First().ToXYZ()
                    );

                mesh.AddTriangleColor(centerWeights, rightWeights, rightWeights);
            }
        }
コード例 #23
0
        private void TriangulateMarshEdge(
            IHexCell center, IHexCell right, float centerV, float rightV, HexDirection direction, IHexMesh mesh
            )
        {
            mesh.AddQuad(
                center.AbsolutePosition + RenderConfig.GetFirstSolidCorner(direction),
                center.AbsolutePosition + RenderConfig.GetSecondSolidCorner(direction),
                right.AbsolutePosition + RenderConfig.GetSecondSolidCorner(direction.Opposite()),
                right.AbsolutePosition + RenderConfig.GetFirstSolidCorner(direction.Opposite())
                );

            mesh.AddQuadUV(0f, 0f, centerV, rightV);
        }
コード例 #24
0
        private void TriangulateCultureCorners_River(
            IHexCell center, IHexCell left, IHexCell right, IHexCell nextRight, HexDirection direction,
            ICivilization centerOwner, ReadOnlyCollection <Vector2> centerRightContour, IHexMesh cultureMesh
            )
        {
            Color cultureColor = centerOwner.Template.Color;

            if (left != null && CivTerritoryLogic.GetCivClaimingCell(left) != centerOwner)
            {
                float ccwTransparency = 1f, cwTransparency;

                Vector2 innerCCW, innerCW, outerCCW, outerCW;

                float cultureWidth = (centerRightContour.First() - center.AbsolutePositionXZ).magnitude * RenderConfig.CultureWidthPercent;

                int i = 0;
                do
                {
                    outerCCW = centerRightContour[i];
                    outerCW  = centerRightContour[i + 1];

                    float distanceFromStart = (centerRightContour.First() - outerCW).magnitude;

                    cwTransparency = Mathf.Clamp01(1f - distanceFromStart / cultureWidth);

                    innerCCW = Vector2.Lerp(outerCCW, center.AbsolutePositionXZ, RenderConfig.CultureWidthPercent);
                    innerCW  = Vector2.Lerp(outerCW, center.AbsolutePositionXZ, RenderConfig.CultureWidthPercent);

                    cultureMesh.AddQuad(
                        new Vector3(innerCCW.x, 0f, innerCCW.y), new Vector3(innerCW.x, 0f, innerCW.y),
                        new Vector3(outerCCW.x, 0f, outerCCW.y), new Vector3(outerCW.x, 0f, outerCW.y)
                        );

                    cultureMesh.AddQuadUV(
                        new Vector2(0f, 0f), new Vector2(0f, 0f), new Vector2(0f, ccwTransparency), new Vector2(0f, cwTransparency)
                        );

                    cultureMesh.AddQuadColor(cultureColor);

                    ccwTransparency = cwTransparency;
                    i++;
                } while(cwTransparency > 0f && i < centerRightContour.Count - 1);
            }

            if (nextRight != null && CivTerritoryLogic.GetCivClaimingCell(nextRight) != centerOwner)
            {
                float cwTransparency = 1f, ccwTransparency;

                Vector2 innerCCW, innerCW, outerCCW, outerCW;

                float cultureWidth = (centerRightContour.Last() - center.AbsolutePositionXZ).magnitude * RenderConfig.CultureWidthPercent;

                int i = centerRightContour.Count - 1;
                do
                {
                    outerCCW = centerRightContour[i - 1];
                    outerCW  = centerRightContour[i];

                    float distanceFromStart = (centerRightContour.Last() - outerCCW).magnitude;

                    ccwTransparency = Mathf.Clamp01(1f - distanceFromStart / cultureWidth);

                    innerCCW = Vector2.Lerp(outerCCW, center.AbsolutePositionXZ, RenderConfig.CultureWidthPercent);
                    innerCW  = Vector2.Lerp(outerCW, center.AbsolutePositionXZ, RenderConfig.CultureWidthPercent);

                    cultureMesh.AddQuad(
                        new Vector3(innerCCW.x, 0f, innerCCW.y), new Vector3(innerCW.x, 0f, innerCW.y),
                        new Vector3(outerCCW.x, 0f, outerCCW.y), new Vector3(outerCW.x, 0f, outerCW.y)
                        );

                    cultureMesh.AddQuadUV(
                        new Vector2(0f, 0f), new Vector2(0f, 0f), new Vector2(0f, ccwTransparency), new Vector2(0f, cwTransparency)
                        );

                    cultureMesh.AddQuadColor(cultureColor);

                    cwTransparency = ccwTransparency;
                    i--;
                }while(ccwTransparency > 0f && i > 0);
            }
        }