Exemple #1
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);
            }
        }
Exemple #2
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);
        }
        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);
        }
Exemple #4
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);
        }
        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));
        }
Exemple #6
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);
        }
Exemple #7
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);
        }
Exemple #8
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
                    );
            }
        }
        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()))
                    {
                    }
                }
            }
        }
Exemple #10
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);
                }
            }
        }