public bool Weldable(HexMetrics.Direction dir)
	{
		switch (dir)
		{
		case HexMetrics.Direction.Up:
			return weldsUp;
		case HexMetrics.Direction.RightUp:
			return weldsRightUp;
		case HexMetrics.Direction.LeftUp:
			return weldsLeftUp;
		case HexMetrics.Direction.Down:
			return weldsDown;
		case HexMetrics.Direction.RightDown:
			return weldsRightDown;
		case HexMetrics.Direction.LeftDown:
			return weldsLeftDown;
		}
		return false;
	}
Esempio n. 2
0
    void TriangulateEdgeTerraces(
        EdgeVertices begin, HexCell beginCell,
        EdgeVertices end, HexCell endCell,
        bool hasRoad
        )
    {
        EdgeVertices e2 = EdgeVertices.TerraceLerp(begin, end, 1);
        Color        c2 = HexMetrics.TerraceLerp(beginCell.Color, endCell.Color, 1);

        TriangulateEdgeStrip(begin, beginCell.Color, e2, c2, hasRoad);

        for (int i = 2; i < HexMetrics.terraceSteps; i++)
        {
            EdgeVertices e1 = e2;
            Color        c1 = c2;
            e2 = EdgeVertices.TerraceLerp(begin, end, i);
            c2 = HexMetrics.TerraceLerp(beginCell.Color, endCell.Color, i);
            TriangulateEdgeStrip(e1, c1, e2, c2, hasRoad);
        }

        TriangulateEdgeStrip(e2, c2, end, endCell.Color, hasRoad);
    }
Esempio n. 3
0
    void TriangulateAdjacentToRiver(
        HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e
        )
    {
        if (cell.HasRoads)
        {
            TriangulateRoadAdjacentToRiver(direction, cell, center, e);
        }

        if (cell.HasRiverThroughEdge(direction.Next()))
        {
            if (cell.HasRiverThroughEdge(direction.Previous()))
            {
                center += HexMetrics.GetSolidEdgeMiddle(direction) *
                          (HexMetrics.innerToOuter * 0.5f);
            }
            else if (
                cell.HasRiverThroughEdge(direction.Previous2())
                )
            {
                center += HexMetrics.GetFirstSolidCorner(direction) * 0.25f;
            }
        }
        else if (
            cell.HasRiverThroughEdge(direction.Previous()) &&
            cell.HasRiverThroughEdge(direction.Next2())
            )
        {
            center += HexMetrics.GetSecondSolidCorner(direction) * 0.25f;
        }

        EdgeVertices m = new EdgeVertices(
            Vector3.Lerp(center, e.v1, 0.5f),
            Vector3.Lerp(center, e.v5, 0.5f)
            );

        TriangulateEdgeStrip(m, cell.Color, e, cell.Color);
        TriangulateEdgeFan(center, m, cell.Color);
    }
Esempio n. 4
0
    void TriangulateEdgeTerraces(EdgeVertices begin, HexCell beginCell,
                                 EdgeVertices end, HexCell endCell,
                                 bool hasRoad)
    {
        EdgeVertices e2 = EdgeVertices.TerraceLerp(begin, end, 1);
        Color        w2 = HexMetrics.TerraceLerp(weights1, weights2, 1);
        float        i1 = beginCell.Index;
        float        i2 = endCell.Index;

        TriangulateEdgeStrip(begin, weights1, i1, e2, w2, i2, hasRoad);

        for (int i = 2; i < HexMetrics.terraceSteps; i++)
        {
            EdgeVertices e1 = e2;
            Color        w1 = w2;
            e2 = EdgeVertices.TerraceLerp(begin, end, i);
            w2 = HexMetrics.TerraceLerp(weights1, weights2, i);
            TriangulateEdgeStrip(e1, w1, i1, e2, w2, i2, hasRoad);
        }

        TriangulateEdgeStrip(e2, w2, i1, end, weights2, i2, hasRoad);
    }
    void TriangulateCornerTerraces(Vector3 begin, HexCell beginCell,
                                   Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell)
    {
        Vector3 v3 = HexMetrics.TerraceLerp(begin, left, 1);
        Vector3 v4 = HexMetrics.TerraceLerp(begin, right, 1);
        Color   c3 = HexMetrics.TerraceLerp(color1, color2, 1);
        Color   c4 = HexMetrics.TerraceLerp(color1, color3, 1);
        Vector3 types;

        types.x = beginCell.TerrainTypeIndex;
        types.y = leftCell.TerrainTypeIndex;
        types.z = rightCell.TerrainTypeIndex;

        //first step
        terrain.AddTriangle(begin, v3, v4);
        terrain.AddTriangleColor(color1, c3, c4);
        terrain.AddTriangleTerrainTypes(types);

        for (int i = 2; i < HexMetrics.terraceSteps; i++)
        {
            Vector3 v1 = v3;
            Vector3 v2 = v4;
            Color   c1 = c3;
            Color   c2 = c4;
            v3 = HexMetrics.TerraceLerp(begin, left, i);
            v4 = HexMetrics.TerraceLerp(begin, right, i);
            c3 = HexMetrics.TerraceLerp(color1, color2, i);
            c4 = HexMetrics.TerraceLerp(color1, color3, i);
            terrain.AddQuad(v1, v2, v3, v4);
            terrain.AddQuadColor(c1, c2, c3, c4);
            terrain.AddQuadTerrainTypes(types);
        }

        //final step
        terrain.AddQuad(v3, v4, left, right);
        terrain.AddQuadColor(c3, c4, color2, color3);
        terrain.AddQuadTerrainTypes(types);
    }
Esempio n. 6
0
    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 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.AddTriangleUnperturbed(
                HexMetrics.Perturb(left), HexMetrics.Perturb(right), boundary
                );
            terrain.AddTriangleColor(
                leftCell.Color, rightCell.Color, boundaryColor
                );
        }
    }
    void TriangulateCornerTerracesCliff(
        Vector3 begin, HexCell beginCell,
        Vector3 left, HexCell leftCell,
        Vector3 right, HexCell rightCell
        )
    {
        float b = 1f / (rightCell.Elevation - beginCell.Elevation);

        if (b < 0)
        {
            b = -b;
        }

        Vector3 boundary      = Vector3.Lerp(HexMetrics.Perturb(begin), HexMetrics.Perturb(right), b);
        Color   boundaryColor = Color.Lerp(color1, color3, b);
        Vector3 types;

        types.x = (float)beginCell.TerrainType;
        types.y = (float)leftCell.TerrainType;
        types.z = (float)rightCell.TerrainType;

        TriangulateBoundaryTriangle(
            begin, color1, left, color2, boundary, boundaryColor, types
            );

        if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope)
        {
            TriangulateBoundaryTriangle(
                left, color2, right, color3, boundary, boundaryColor, types
                );
        }
        else
        {
            terrain.AddTriangleUnPerturbed(HexMetrics.Perturb(left), HexMetrics.Perturb(right), boundary);
            terrain.AddTriangleColor(color2, color3, boundaryColor);
            terrain.AddTriangleTerrainTypes(types);
        }
    }
Esempio n. 8
0
    void TriangulateOpenWater(
        HexDirection direction, HexCell cell, HexCell neighbor, Vector3 center
        )
    {
        Vector3 c1 = center + HexMetrics.GetFirstWaterCorner(direction);
        Vector3 c2 = center + HexMetrics.GetSecondWaterCorner(direction);

        water.AddTriangle(center, c1, c2);
        Vector3 indices;

        indices.x = indices.y = indices.z = cell.Index;
        water.AddTriangleCellData(indices, weights1);

        if (direction <= HexDirection.SE && neighbor != null)
        {
            Vector3 bridge = HexMetrics.GetWaterBridge(direction);
            Vector3 e1     = c1 + bridge;
            Vector3 e2     = c2 + bridge;

            water.AddQuad(c1, c2, e1, e2);
            indices.y = neighbor.Index;
            water.AddQuadCellData(indices, weights1, weights2);

            if (direction <= HexDirection.E)
            {
                HexCell nextNeighbor = cell.GetNeighbor(direction.Next());
                if (nextNeighbor == null || !nextNeighbor.IsUnderwater)
                {
                    return;
                }
                water.AddTriangle(
                    c2, e2, c2 + HexMetrics.GetWaterBridge(direction.Next())
                    );
                indices.z = nextNeighbor.Index;
                water.AddTriangleCellData(indices, weights1, weights2, weights3);
            }
        }
    }
Esempio n. 9
0
    private void RightTrangulateConnection(HexDirectionEnum direction, HexCell cell, Vector3 v1, Vector3 v2)
    {
        HexCell neighbor = cell.GetNeighbor(direction);

        if (neighbor == null)
        {
            NoNeighborConnection(direction, cell, v1, v2);
            return;
        }
        Vector3 bridge = HexMetrics.GetTwoBridge(direction);
        Vector3 v3     = v1 + bridge;
        Vector3 v4     = v2 + bridge;

        AddQuad(v1, v2, v3, v4);
        AddQuadColor(cell.color, neighbor.color);

        HexCell nextNeighbor = cell.GetNeighbor(direction.Next());

        if (nextNeighbor != null)
        {
            AddTriangle(v2, v4, v2 + HexMetrics.GetTwoBridge(direction.Next()));
            AddTriangleColor(cell.color, neighbor.color, nextNeighbor.color);
        }
        else
        {
            //绘制缺失的小三角
            AddTriangle(v2, v4, cell.center + HexMetrics.GetSecondConrner(direction));
            AddTriangleColor(cell.color, neighbor.color, (cell.color + neighbor.color) * 0.5f);
        }
        //绘制缺失的小三角
        HexCell prevNeighbor = cell.GetNeighbor(direction.Previous());

        if (prevNeighbor == null)
        {
            AddTriangle(v1, cell.center + HexMetrics.GetFirstCorner(direction), v3);
            AddTriangleColor(cell.color, (cell.color + cell.color + neighbor.color) / 3f, neighbor.color);
        }
    }
    /// <summary>
    /// Creates the triangles for a side of the hexagon, when there is a river in the hex.
    /// </summary>
    void TriangulateAdjacentToRiver(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e)
    {
        if (cell.HasRoads)
        {
            TriangulateRoadAdjacentToRiver(direction, cell, center, e);
        }

        // Determine center by finding river channel center edge
        if (cell.HasRiverThroughEdge(direction.Next()))
        {
            if (cell.HasRiverThroughEdge(direction.Previous()))
            {
                center += HexMetrics.GetSolidEdgeMiddle(direction) * (HexMetrics.InnerToOuter * 0.5f);
            }
            else if (cell.HasRiverThroughEdge(direction.Previous2()))
            {
                center += HexMetrics.GetFirstSolidCorner(direction) * 0.25f;
            }
        }
        else if (cell.HasRiverThroughEdge(direction.Previous()) && cell.HasRiverThroughEdge(direction.Next2()))
        {
            center += HexMetrics.GetSecondSolidCorner(direction) * 0.25f;
        }

        EdgeVertices m = new EdgeVertices(
            Vector3.Lerp(center, e.v1, 0.5f),
            Vector3.Lerp(center, e.v5, 0.5f)
            );

        TriangulateEdgeStrip(m, weights1, cell.Index, e, weights1, cell.Index);
        TriangulateEdgeFan(center, m, cell.Index);

        // If possible add any features
        if (!cell.IsUnderwater && !cell.HasRoadThroughEdge(direction))
        {
            Features.AddFeature(cell, (center + e.v1 + e.v5) * (1f / 3f));
        }
    }
Esempio n. 11
0
    void AddWallSegment(
        Vector3 nearLeft, Vector3 farLeft, Vector3 nearRight, Vector3 farRight
        )
    {
        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;

        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;

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

        walls.AddQuadUnperturbed(t1, t2, v3, v4);
    }
Esempio n. 12
0
    private void InitGhostCell()
    {
        Debug.Log("Scaling ghost cell");

        ghostCellPrefab = GameObject.Instantiate(ghostCellPrefab);
        //Scale the cell so it is the correct size
        Vector3 targetSize = new Vector3(HexMetrics.ScaledInnerRadius(terrain) * 2, HexMetrics.ScaledHeight(terrain), HexMetrics.ScaledOuterRadius(terrain) * 2);

        GameUtils.ScaleGameObjectToSize(ghostCellPrefab, targetSize);

        //Set the initial position of the ghost cell
        ghostCellPrefab.transform.position = terrain.transform.position;

        //Apply the ghost material to the ghost cell
        MeshRenderer ghostRenderer = ghostCellPrefab.GetComponent <MeshRenderer>();

        Material[] ghostMaterials = new Material[ghostRenderer.materials.Length];
        for (int i = 0; i < ghostMaterials.Length; i++)
        {
            ghostMaterials[i] = ghostMaterial;
        }
        ghostRenderer.materials = ghostMaterials;
    }
Esempio n. 13
0
    public override void Triangulate(HexMesh mesh)
    {
        float lerpCoef = (float)(leftCell.Elevation - beginCell.Elevation) / (rightCell.Elevation - beginCell.Elevation);

        if (lerpCoef < 0)
        {
            lerpCoef = -lerpCoef;
        }
        Vector3 boundary      = Vector3.Lerp(HexMetrics.Perturb(beginCorner), HexMetrics.Perturb(rightCorner), lerpCoef);
        Color   boundaryColor = Color.Lerp(beginCell.Color, rightCell.Color, lerpCoef);

        Corner.TriangulateBoundaryTriangle(mesh, beginCorner, beginCell, leftCorner, leftCell, boundary, boundaryColor);

        if (HexMetrics.GetEdgeType(leftCell.Elevation, rightCell.Elevation) == HexEdgeType.Slope)
        {
            Corner.TriangulateBoundaryTriangle(mesh, leftCorner, leftCell, rightCorner, rightCell, boundary, boundaryColor);
        }
        else
        {
            mesh.AddTriangle(HexMetrics.Perturb(leftCorner), HexMetrics.Perturb(rightCorner), boundary, false);
            mesh.AddTriangleColor(leftCell.Color, rightCell.Color, boundaryColor);
        }
    }
Esempio n. 14
0
    private void TriangulateConnection(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e1)
    {
        HexCell neighbor = cell.GetNeighbor(direction);

        if (neighbor == null)
        {
            return;
        }

        Vector3      bridge = HexMetrics.GetBridge(direction);
        EdgeVertices e2     = new EdgeVertices(e1.v1 + bridge, e1.v4 + bridge);

        TriangulateEdgeStrip(e1, e2, cell.color, neighbor.color);

        HexDirection nextDirection = direction.Next();
        HexCell      nextNeighbor  = cell.GetNeighbor(nextDirection);

        if (direction <= HexDirection.E && nextNeighbor != null)
        {
            AddTriangle(e1.v4, e2.v4, e1.v4 + HexMetrics.GetBridge(nextDirection));
            AddTriangleColor(cell.color, neighbor.color, nextNeighbor.color);
        }
    }
Esempio n. 15
0
    void Precalculation(HexCell cell)
    {
        cell.Center        = cell.WaterCenter = cell.transform.localPosition;
        cell.WaterCenter.y = HexMetrics.WaterSurfaceY;

        for (int i = 0; i <= 5; i++)
        {
            var direction = (HexDirection)i;

            cell.Edges[i] = new EdgeVertices(
                cell.Center + HexMetrics.GetLeftSolidCorner(direction),
                cell.Center + HexMetrics.GetRightSolidCorner(direction));

            if (cell.HasRiver && cell.HasRiverThroughEdge(direction))
            {
                cell.Edges[i].V3.y = cell.StreamBedY;
            }

            cell.WaterEdges[i] = new EdgeVertices(
                cell.WaterCenter + HexMetrics.GetLeftWaterCorner(direction),
                cell.WaterCenter + HexMetrics.GetRightWaterCorner(direction));
        }
    }
Esempio n. 16
0
    /// <summary>
    /// 三角化瀑布
    /// </summary>
    /// <param name="v1">从瀑布上方,自上而下看,上方左边的顶点</param>
    /// <param name="v2">上右顶点</param>
    /// <param name="v3">下左顶点</param>
    /// <param name="v4">下右顶点</param>
    /// <param name="y1">上方所在六边形河流高度</param>
    /// <param name="y2">下方所在六边形河流高度</param>
    /// <param name="waterY">下方水平面高度</param>
    void TriangulateWaterfallInWater(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, float y1, float y2, float waterY, Vector3 indices)
    {
        // 让桥边线顶点高度变成河流高度
        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);

        // 用插值的方法获得v3->v1向量、v4->v2向量与水平面的交点
        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);
        rivers.AddQuadCellData(indices, weights1, weights2);
    }
Esempio n. 17
0
    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);

        terrain.AddTriangleUnperturbed(HexMetrics.Perturb(begin), v2, boundary);
        terrain.AddTriangleColor(beginCell.Color, c2, boundaryColor);

        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.AddTriangleUnperturbed(v1, v2, boundary);
            terrain.AddTriangleColor(c1, c2, boundaryColor);
        }

        terrain.AddTriangleUnperturbed(v2, HexMetrics.Perturb(left), boundary);
        terrain.AddTriangleColor(c2, leftCell.Color, boundaryColor);
    }
Esempio n. 18
0
    public void TriangulateCornerCliffTerraces(Vector3 begin, HexCell beginCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell)
    {
        float   b               = Mathf.Abs(1f / (leftCell.Elevation - beginCell.Elevation));
        Vector3 boundary        = Vector3.Lerp(HexMetrics.PerturbVector(begin), HexMetrics.PerturbVector(left), b);
        Color   boundaryWeights = Color.Lerp(Weights1, Weights2, b);
        Vector3 indices;

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

        TriangulateBoundaryTriangle(right, rightCell, begin, beginCell, boundary, boundaryWeights, indices);

        if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope)
        {
            TriangulateBoundaryTriangle(left, leftCell, right, rightCell, boundary, boundaryWeights, indices);
        }
        else
        {
            Terrain.AddTriangleUnperturbed(HexMetrics.PerturbVector(left), HexMetrics.PerturbVector(right), boundary);
            Terrain.AddTriangleCellData(indices, Weights1, Weights2, boundaryWeights);
        }
    }
Esempio n. 19
0
    private void TriangulateEdgeTerraces(EdgeVertices begin, HexCell beginCell, EdgeVertices end, HexCell endCell,
                                         bool hasRoad)
    {
        var e2 = EdgeVertices.TerraceLerp(begin, end, 1);
        var w2 = HexMetrics.TerraceLerp(weights1, weights2, 1);
        var i1 = beginCell.Index;
        var i2 = endCell.Index;

        TriangulateEdgeStrip(begin, weights1, i1, e2, w2, i2, hasRoad);

        for (var i = 2; i < HexMetrics.terraceSteps; i++)
        {
            var e1 = e2;
            var c1 = w2;

            e2 = EdgeVertices.TerraceLerp(begin, end, i);
            w2 = HexMetrics.TerraceLerp(weights1, weights2, i);

            TriangulateEdgeStrip(e1, c1, i1, e2, w2, i2, hasRoad);
        }

        TriangulateEdgeStrip(e2, w2, i1, end, weights2, i2, hasRoad);
    }
Esempio n. 20
0
    protected static void TriangulateBoundaryTriangle(
        HexMesh mesh,
        Vector3 beginCorner, HexCell beginCell,
        Vector3 leftCorner, HexCell leftCell,
        Vector3 boundary, Color boundaryColor
        )
    {
        Vector3 v1 = beginCorner;
        Color   c1 = beginCell.Color;

        for (int step = 1; step < HexMetrics.terraceSteps + 1; ++step)
        {
            Vector3 v3 = HexMetrics.TerraceLerp(beginCorner, leftCorner, step);

            Color c3 = HexMetrics.ColorLerp(beginCell.Color, leftCell.Color, step);

            mesh.AddTriangle(HexMetrics.Perturb(v1), HexMetrics.Perturb(v3), boundary, false);
            mesh.AddTriangleColor(c1, c3, boundaryColor);

            v1 = v3;
            c1 = c3;
        }
    }
Esempio n. 21
0
    /// <summary>
    /// 通过世界内的一个点(vector3),经过彩色噪点图扰动后,返回扰动后的Vect3
    /// </summary>
    /// <param name="position">世界坐标内的点</param>
    /// <returns>经过噪点图扰动后的点坐标</returns>
    private Vector3 Perturb(Vector3 position)
    {
        //利用世界空间内一点,在彩色噪点图上进行采样,得到彩色噪点图内一点的RGBA信息
        Vector4 sample = HexMetrics.SampleNoise(position);

        //使用原始坐标加上噪点图的采样坐标,得到扰动后坐标
        //position.x += sample.x;
        //position.y += sample.y;
        //position.z += sample.z;

        //将采样后的扰动结果控制在1到-1之间
        //position.x += sample.x * 2f - 1f;
        //position.y += sample.y * 2f - 1f;
        //position.z += sample.z * 2f - 1f;

        //增加了每个点的扰动强度
        position.x += (sample.x * 2f - 1f) * HexMetrics.cellPerturbStrength;
        //为了让cell表面变得平坦,这里不再在垂直方向上进行扰动。
        //position.y += (sample.y * 2f - 1f) * HexMetrics.cellPerturbStrength;
        position.z += (sample.z * 2f - 1f) * HexMetrics.cellPerturbStrength;

        return(position);
    }
Esempio n. 22
0
    //绘制绝壁三角
    private void TriangulateCornerTerracesCliff(Vector3 begin, HexCell beginCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell)
    {
        float   b               = Mathf.Abs(1f / (rightCell.Elevation - beginCell.Elevation));
        Vector3 boundary        = Vector3.Lerp(HexMetrics.Perturb(begin), HexMetrics.Perturb(right), b);
        Color   boundaryWeights = Color.Lerp(weights1, weights3, b);
        Vector3 indices;

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

        TriangulateBoundaryTriangle(begin, weights1, left, weights2, boundary, boundaryWeights, indices);

        if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope)
        {
            TriangulateBoundaryTriangle(left, weights2, right, weights3, boundary, boundaryWeights, indices);
        }
        else
        {
            AddTerrainTriangle(HexMetrics.Perturb(left), HexMetrics.Perturb(right), boundary);
            terrain.AddTriangleCellData(indices, weights2, weights3, boundaryWeights);
        }
    }
    void TriangulateEdgeTerraces(EdgeVertices begin, HexCell beginCell,
                                 EdgeVertices end, HexCell endCell, bool hasRoad)
    {
        EdgeVertices e2 = EdgeVertices.TerraceLerp(begin, end, 1);
        Color        c2 = HexMetrics.TerraceLerp(color1, color2, 1);
        float        t1 = beginCell.TerrainTypeIndex;
        float        t2 = endCell.TerrainTypeIndex;

        // bottom quad
        TriangulateEdgeStrip(begin, color1, t1, e2, c2, t2, hasRoad);

        for (int i = 2; i < HexMetrics.terraceSteps; i++)
        {
            EdgeVertices e1 = e2;
            Color        c1 = c2;
            e2 = EdgeVertices.TerraceLerp(begin, end, i);
            c2 = HexMetrics.TerraceLerp(color1, color2, i);
            TriangulateEdgeStrip(e1, c1, t1, e2, c2, t2, hasRoad);
        }

        // final quad
        TriangulateEdgeStrip(e2, c2, t1, end, color2, t2, hasRoad);
    }
    void TriangulateEdgeTerraces(
        EdgeVertices begin, HexCell beginCell,
        EdgeVertices end, HexCell endCell
        )
    {
        EdgeVertices e2 = EdgeVertices.TerraceLerp(begin, end, 1);
        Color        c2 = HexMetrics.TerraceLerp(color1, color2, 1);
        float        t1 = (float)beginCell.TerrainType;
        float        t2 = (float)endCell.TerrainType;

        TriangulateEdgeStrip(begin, color1, t1, e2, c2, t2);

        for (int i = 2; i < HexMetrics.terraceSteps; i++)
        {
            EdgeVertices e1 = e2;
            Color        c1 = c2;
            e2 = EdgeVertices.TerraceLerp(begin, end, i);
            c2 = HexMetrics.TerraceLerp(color1, color2, i);
            TriangulateEdgeStrip(e1, c1, t1, e2, c2, t2);
        }

        TriangulateEdgeStrip(e2, c2, t1, end, color2, t2);
    }
    /// <summary>
    /// Creates geometry for connecting terraces with a cliff.
    /// </summary>
    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);

        // Boundary must not suffer from noise or terraces and cliffs are impossible to merge
        // Use AddTriangleUnperturbed and perturb vertices other than boundary, v2 is perturbed at creation
        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);
    }
Esempio n. 26
0
    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.AddTriangleUnperturbed(v2, HexMetrics.Perturb(left), boundary);
        terrain.AddTriangleCellData(indices, w2, leftWeights, boundaryWeights);
    }
Esempio n. 27
0
    /// <summary>
    /// 构建阶梯状连接区域
    /// 这里不再使用单一的顶点,而是直接使用cell与阶梯区域相连接的边,通过计算得出边上的顶点位置以及每个顶点的颜色
    /// </summary>
    /// <param name="begin">第一个cell与相邻阶梯化区域的边上顶点</param>
    /// <param name="beginCell">第一个cell的实例</param>
    /// <param name="end">第二个cell与相邻阶梯化区域的边上顶点</param>
    /// <param name="endCell">第二个cell的实例</param>
    private void TriangulateEdgeTerraces(EdgeVertices begin, HexCell beginCell, EdgeVertices end, HexCell endCell)
    {
        //通过插值计算出相邻cell边的每个坐标点
        EdgeVertices e2 = EdgeVertices.TerraceLerp(begin, end, 1);
        //通过插值计算出相邻cell边每个坐标点的颜色
        Color c2 = HexMetrics.TerraceLerp(beginCell.Color, endCell.Color, 1);

        //构建阶梯的第一段
        TriangulateEdgeStrip(begin, beginCell.Color, e2, c2);

        //循环生成中间部分
        for (int i = 2; i < HexMetrics.terraceSteps; i++)
        {
            EdgeVertices e1 = e2;
            Color        c1 = c2;
            e2 = EdgeVertices.TerraceLerp(begin, end, i);
            c2 = HexMetrics.TerraceLerp(beginCell.Color, endCell.Color, i);
            TriangulateEdgeStrip(e1, c1, e2, c2);
        }

        //构建阶梯的最后一段
        TriangulateEdgeStrip(e2, c2, end, endCell.Color);
    }
Esempio n. 28
0
    //绘制斜坡小三角
    private void TriangulateCornerTerraces(Vector3 begin, HexCell beginCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell)
    {
        Vector3 v3 = begin;
        Vector3 v4 = begin;
        Color   w3 = weights1;
        Color   w4 = weights1;

        Vector3 indices;

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

        for (int i = 1; i <= HexMetrics.terraceSetps; i++)
        {
            Vector3 v1 = v3;
            Vector3 v2 = v4;
            Color   w1 = w3;
            Color   w2 = w4;
            v3 = HexMetrics.TerraceLerp(begin, left, i);
            v4 = HexMetrics.TerraceLerp(begin, right, i);
            w3 = HexMetrics.TerraceLerp(weights1, weights2, i);
            w4 = HexMetrics.TerraceLerp(weights1, weights3, i);

            if (v1 == v2)
            {
                AddTerrainPerturTriangle(v1, v3, v4);
                terrain.AddTriangleCellData(indices, w1, w3, w4);
            }
            else
            {
                AddTerrainQuad(v1, v2, v3, v4);

                terrain.AddQuadCellData(indices, w1, w2, w3, w4);
            }
        }
    }
Esempio n. 29
0
    /// <summary>
    /// 制作角落的梯田坡
    /// 三个六边形组成的角落,只有一种高度变化,形成的梯田型的角落
    /// </summary>
    /// <param name="begin"></param>
    /// <param name="beginCell"></param>
    /// <param name="left"></param>
    /// <param name="leftCell"></param>
    /// <param name="right"></param>
    /// <param name="rightCell"></param>
    void TriangulateCornerTerraces(
        Vector3 begin, HexCell beginCell,
        Vector3 left, HexCell leftCell,
        Vector3 right, HexCell rightCell
        )
    {
        //角落梯田第一步数,是个三角面---------
        Vector3 v3 = HexMetrics.TerraceLerp(begin, left, 1);
        Vector3 v4 = HexMetrics.TerraceLerp(begin, right, 1);
        Color   c3 = HexMetrics.TerraceLerp(beginCell.Color, leftCell.Color, 1);
        Color   c4 = HexMetrics.TerraceLerp(beginCell.Color, rightCell.Color, 1);

        terrain.AddTriangle(begin, v3, v4);
        terrain.AddTriangleColor(beginCell.Color, c3, c4);
        //----------------------------------

        //中间步数梯田,是矩形面片----------------------
        for (int i = 2; i < HexMetrics.terraceSteps; i++)
        {
            Vector3 v1 = v3;
            Vector3 v2 = v4;
            Color   c1 = c3;
            Color   c2 = c4;
            v3 = HexMetrics.TerraceLerp(begin, left, i);
            v4 = HexMetrics.TerraceLerp(begin, right, i);
            c3 = HexMetrics.TerraceLerp(beginCell.Color, leftCell.Color, i);
            c4 = HexMetrics.TerraceLerp(beginCell.Color, rightCell.Color, i);
            terrain.AddQuad(v1, v2, v3, v4);
            terrain.AddQuadColor(c1, c2, c3, c4);
        }
        //-------------------------------------------

        //最后一步数矩形梯田-------------------------
        terrain.AddQuad(v3, v4, left, right);
        terrain.AddQuadColor(c3, c4, leftCell.Color, rightCell.Color);
        //-------------------------------------
    }
Esempio n. 30
0
    void Triangulate(HexDirection direction, HexCell cell)
    {
        //纯色区域三角化使用单一颜色
        Vector3 center = cell.transform.localPosition;
        Vector3 v1     = center + HexMetrics.GetFirstSolidCorner(direction);
        Vector3 v2     = center + HexMetrics.GetSecondSolidCorner(direction);

        AddTriangle(center, v1, v2);
        AddTriangleColor(cell.color);
        //梯形混色区域
        Vector3 bridge = HexMetrics.GetBridge(direction);
        Vector3 v3     = v1 + bridge;
        Vector3 v4     = v2 + bridge;

        AddQuad(v1, v2, v3, v4);
        HexCell prevNeighbor = cell.GetNeighbor(direction.Previous()) ?? cell;
        HexCell neighbor     = cell.GetNeighbor(direction) ?? cell;
        HexCell nextNeighbor = cell.GetNeighbor(direction.Next()) ?? cell;

        AddQuadColor(cell.color,
                     (cell.color + prevNeighbor.color + neighbor.color) * 0.5f);
        //补上被剔除的两个三角形(第一个三角形三个顶点的颜色分别是v1本色,2三个六边形混色,3桥色)
        Color bridgeColor = (cell.color + neighbor.color) * 0.5f;

//        AddQuadColor(cell.color, bridgeColor);
        AddTriangle(v1, center + HexMetrics.GetFirstCorner(direction), v3);
        AddExcludedTriangleColor(
            cell.color,
            (cell.color + prevNeighbor.color + neighbor.color) / 3f,
            bridgeColor);
        AddTriangle(v2, v4, center + HexMetrics.GetSecondCorner(direction));
        AddExcludedTriangleColor(
            cell.color,
            bridgeColor,
            (cell.color + neighbor.color + nextNeighbor.color) / 3f
            );
    }
Esempio n. 31
0
    public static Mesh CreateMesh(float size)
    {
        var vertices  = new List <Vector3>();
        var uv        = new List <Vector2>();
        var triangles = new List <int>();

        vertices.Add(Vector3.zero);
        uv.Add(Vector2.zero);

        foreach (var corner in HexMetrics.HexCorners(size))
        {
            vertices.Add(corner);
            uv.Add(Vector2.one);
        }

        for (int i = 1; i < HexMetrics.CornerNums; i++)
        {
            triangles.Add(0);
            triangles.Add(i);
            triangles.Add(i + 1);
        }

        // 循环一周
        triangles.Add(0);
        triangles.Add(HexMetrics.CornerNums);
        triangles.Add(1);

        var mesh = new Mesh();

        mesh.vertices  = vertices.ToArray();
        mesh.uv        = uv.ToArray();
        mesh.triangles = triangles.ToArray();
        mesh.RecalculateNormals();
        mesh.RecalculateBounds();

        return(mesh);
    }
Esempio n. 32
0
	public static IntVector2 GetGridOffset (HexMetrics.Direction direction)
	{
		switch (direction)
		{
			case HexMetrics.Direction.Up: 		 return new IntVector2( 0, 1);
			case HexMetrics.Direction.RightUp: 	 return new IntVector2( 1, 0);
			case HexMetrics.Direction.RightDown: return new IntVector2( 1,-1);
			case HexMetrics.Direction.Down: 	 return new IntVector2( 0,-1);
			case HexMetrics.Direction.LeftDown:	 return new IntVector2(-1, 0);
			case HexMetrics.Direction.LeftUp:	 return new IntVector2(-1, 1);
		}
		
		return null;
//		return new Dictionary<HexMetrics.Direction, System.Func<IntVector2>>()
//		{
//			{HexMetrics.Direction.Up, 		() => new IntVector2( 0, 1)},
//			{HexMetrics.Direction.RightUp, 	() => new IntVector2( 1, 0)},
//			{HexMetrics.Direction.RightDown,() => new IntVector2( 1,-1)},
//			{HexMetrics.Direction.Down, 	() => new IntVector2( 0,-1)},
//			{HexMetrics.Direction.LeftDown,	() => new IntVector2(-1, 0)},
//			{HexMetrics.Direction.LeftUp,	() => new IntVector2(-1, 1)}
//			
//		}
	}
Esempio n. 33
0
	public Vector2 GetDirection (HexMetrics.Direction direction)
	{
		return new Dictionary<HexMetrics.Direction, System.Func<Vector2>>()
		{
			{HexMetrics.Direction.Up, 		() =>  Up},
			{HexMetrics.Direction.RightUp, 	() =>  RightUp},
			{HexMetrics.Direction.RightDown,() =>  RightDown},
			{HexMetrics.Direction.Down, 	() => -Up},
			{HexMetrics.Direction.LeftDown,	() => -RightUp},
			{HexMetrics.Direction.LeftUp,	() => -RightDown}
			
		}[direction]();
	}
	public static HexMetrics.Direction Reverse(HexMetrics.Direction direction)
	{
		return ReverseDirection(direction);
	}
	//=========================================================================================
	#region Direction Functions
	
	/*
	 * SimulationOrientation - Orientation the cell is oriented relative to up
	 * RelativeDirection - a direction relative to SimulationOrientation
	 * AbsoluteDirection - a direction relative to Up
	 * 
	 * */
	
	public void RotatateSimulationOrientation(HexMetrics.Direction offset)
	{
		RotatateSimulationOrientation((int)offset);
	}
	public static int RotationDifference(HexMetrics.Direction a)
	{
		return RotationDifference(a, HexMetrics.Direction.Up);
	}
	public static int RotationDifference(HexMetrics.Direction a, HexMetrics.Direction b)
	{
		HexMetrics.Direction diff = (HexMetrics.Direction)((int)a-(int)b);
		return (((int)diff+3)%6)-3;
	}
	public HexMetrics.Direction Absolute(HexMetrics.Direction relativeDirection)
	{
		return AbsoluteDirectionFromRelative(relativeDirection);
	}
//	public GrabbablePart GetConnectedPartAtRelative(HexMetrics.Direction relativeDirection)
//	{
//		return _connectedParts[Absolute(relativeDirection)].connectedPart;
//	}
	
	public GrabbablePart GetConnectedPart(HexMetrics.Direction relativeDirection)
	{
		return _connectedParts[(int)relativeDirection].connectedPart;
	}
	public HexMetrics.Direction AbsoluteDirectionFromRelative(HexMetrics.Direction relativeDirection)
	{
		return (HexMetrics.Direction)( ((int)relativeDirection + (int)SimulationOrientation) % 6);
	}
//	public void ConnectPartAndPlaceAtAbsoluteDirection(GrabbablePart otherPart, PhysicalConnectionType connectionType, HexMetrics.Direction absoluteDirection)
//	{
//		ConnectPartAndPlaceAtRelativeDirection(otherPart, connectionType, Relative(absoluteDirection));
//	}
	
	public void ConnectPartAndPlaceAtRelativeDirection(GrabbablePart otherPart, PhysicalConnectionType connectionType, HexMetrics.Direction relativeDirection)
	{
		HexMetrics.Direction absoluteDirection = Absolute(relativeDirection);
		ConnectionDescription connDesc = _connectedParts[(int)relativeDirection];
		
		connDesc.connectedPart = otherPart; // connect the part
		
		ConnectionDescription otherConnDesc = otherPart._connectedParts[(int)ConnectedsOpposite(relativeDirection)]; // get the other parts opposite side that is connected to this
		
		otherConnDesc.connectedPart = this; // connect that side
		
		connDesc.connectedPart.transform.position = transform.position + (Vector3)GameSettings.instance.hexCellPrefab.GetDirection(absoluteDirection);
		
		SetPhysicalConnection(relativeDirection, connectionType);
		
		if (ParentConstruction != null)
		{
//			Debug.Log("Adding to construction "+ParentConstruction.name);
			ParentConstruction.AddToConstruction(otherPart);
		}
		
	}
	public void SetAuxilaryConnections(HexMetrics.Direction relativeDirection, int newConnectionTypes)
	{
		ConnectionDescription connDesc = _connectedParts[(int)relativeDirection];
		if (connDesc.connectedPart == null)
		{
			connDesc.auxConnectionTypes = 0;
			return;
		}
		
		HexMetrics.Direction oppositeDirection = ConnectedsOpposite(relativeDirection);
		ConnectionDescription otherConnDesc = connDesc.connectedPart._connectedParts[(int)oppositeDirection];
		
		bool weldableHere = Weldable(relativeDirection);
		bool weldabelThere = connDesc.connectedPart.Weldable(oppositeDirection);
		
		if (weldableHere && weldabelThere)
		{
			connDesc.auxConnectionTypes = newConnectionTypes;
			otherConnDesc.auxConnectionTypes = newConnectionTypes;
		}
		else
		{
			connDesc.auxConnectionTypes = 0;
			otherConnDesc.auxConnectionTypes = 0;
		}
	}
	public HexMetrics.Direction ConnectedsOpposite(HexMetrics.Direction relativeDirection)
	{
		return ConnectedPartsOppositeDirection(relativeDirection);
	}
	public int GetAuxilaryConnectionTypes(HexMetrics.Direction relativeDirection)
	{
		if (GetConnectedPart(relativeDirection) == null)
		{
			return 0;
		}
		return _connectedParts[(int)relativeDirection].auxConnectionTypes;
	}
	public HashSet<Construction> SetPhysicalConnection(HexMetrics.Direction relativeDirection, 
													PhysicalConnectionType newConnectionType, 
													SplitOptions splitOption)
	{
		ConnectionDescription connDesc = _connectedParts[(int)relativeDirection];
//		PhysicalConnectionType originalConnection = connDesc.connectionType;
		if (connDesc.connectedPart == null)
		{
			
			// disconnecting part
			connDesc.connectionType = PhysicalConnectionType.None;
			SetWeldSprite(relativeDirection, false);
			
			if (ParentConstruction != null)
			{
				if (splitOption == SplitOptions.SplitIfNecessary)
				{
					return ParentConstruction.CheckForSplitsOrJoins();
				}
				return new HashSet<Construction> { ParentConstruction };
			}
			
			return new HashSet<Construction> ();
		}
		
		HexMetrics.Direction oppositeDirection = ConnectedsOpposite(relativeDirection);
		ConnectionDescription otherConnDesc = connDesc.connectedPart._connectedParts[(int)oppositeDirection];
		
		bool weldableHere = Weldable(relativeDirection);
		bool weldableThere = connDesc.connectedPart.Weldable(oppositeDirection);
//		Debug.Log("Checking weldability: "+direction+"("+weldableHere+") <-> "+oppositeDirection+"("+weldabelThere+")");
		if (weldableHere && weldableThere)
		{
			connDesc.connectionType = newConnectionType;
			otherConnDesc.connectionType = newConnectionType;
		}
		else
		{
			connDesc.connectionType = PhysicalConnectionType.None;
			otherConnDesc.connectionType = PhysicalConnectionType.None;
		}
		
		// update the weld sprites
		SetWeldSprite(relativeDirection, connDesc.connectionType != PhysicalConnectionType.None);
		connDesc.connectedPart.SetWeldSprite(oppositeDirection, connDesc.connectionType != PhysicalConnectionType.None);
		
		
		//if we are disconnecting the side (None) or if it's not weldable, make sure that the parts are not connected
		if (connDesc.connectionType == PhysicalConnectionType.None)
		{
			otherConnDesc.connectedPart = null;
			connDesc.connectedPart = null;
			
			if (ParentConstruction == null)
			{
				Debug.LogWarning ("Parent is null!");
			}
			else
			{
				// check that by disconnecting a side, we have not split the construction up
				if (splitOption == SplitOptions.SplitIfNecessary)
				{
					return ParentConstruction.CheckForSplitsOrJoins();
				}
				return new HashSet<Construction> { ParentConstruction };
			}
		}
		if (ParentConstruction != null)
		{
			return new HashSet<Construction> { ParentConstruction };
		}
		return new HashSet<Construction>();
	}
	public HashSet<Construction> SetPhysicalConnection(HexMetrics.Direction relativeDirection, 
													PhysicalConnectionType newConnectionType)
	{
		return SetPhysicalConnection(relativeDirection, newConnectionType, SplitOptions.SplitIfNecessary);
	}
	private void SetWeldSprite(HexMetrics.Direction relativeDirection, bool show)
	{
		GameObject weldSprite = _weldSpriteObjects[(int)relativeDirection];
		if (weldSprite != null)
		{
			weldSprite.transform.localScale = Vector3.one * (show ? 1 : 0);
		}
	}
	public PhysicalConnectionType GetPhysicalConnectionType(HexMetrics.Direction relativeDirection)
	{
		if (GetConnectedPart(relativeDirection) == null)
		{
			return PhysicalConnectionType.None;
		}
		return _connectedParts[(int)relativeDirection].connectionType;
	}
	public static HexMetrics.Direction ReverseDirection(HexMetrics.Direction direction)
	{
		return (HexMetrics.Direction)( ((int)direction+3)%6 );
	}
	public HexMetrics.Direction ConnectedPartsOppositeDirection(HexMetrics.Direction relativeDirection)
	{
		GrabbablePart connectedPart = GetConnectedPart(relativeDirection);
		if (connectedPart == null)
			return (HexMetrics.Direction)(-1);
		
		return OtherPartsOppositeDirection(relativeDirection, connectedPart);
	}
	public HexMetrics.Direction RelativeDirectionFromAbsolute(HexMetrics.Direction absoluteDirection)
	{
		return (HexMetrics.Direction)( ((int)absoluteDirection + 6 - (int)SimulationOrientation) % 6);
	}
	public HashSet<Construction> SetSimulationOrientation(HexMetrics.Direction orientation)
	{
		
		for (int i = 0 ; i < 6 ; i++)
		{
			if ( _connectedParts[i] == null)
			{
				 _connectedParts[i] = new ConnectionDescription();
			}
		}
		
//			adjacent.ForEach((obj) => obj.parent = null);
		int directionChange = ((int)orientation - (int)SimulationOrientation + 6)%6;
		transform.rotation = Quaternion.Euler(0, 0, (int)orientation * -60);
		
		ConnectionDescription [] newParts = new ConnectionDescription [6];
		PhysicalConnectionType [] physicalConnections = new PhysicalConnectionType [6];
		int [] auxilaryConnections = new int [6];
		
//			adjacent.ForEach((obj) => obj.parent = transform);
		
		for (int i = 0 ; i < 6 ; i++)
		{
			int newDirection = (i+directionChange)%6;
			newParts[i] = _connectedParts[newDirection];
			
			physicalConnections[i] = _connectedParts[newDirection].connectionType;
			auxilaryConnections[i] = _connectedParts[newDirection].auxConnectionTypes;
		}
		for (int i = 0 ; i < 6 ; i++)
		{
			int newDirection = (i+directionChange)%6;
			_connectedParts[i] = newParts[i];
			
			if (_connectedParts[i].connectedPart == null)
			{
				physicalConnections[i] = PhysicalConnectionType.None;
				auxilaryConnections[i] = 0;
			}
//			Debug.Log ("Replacing Connection ("+(HexMetrics.Direction)newDirection+") "+ _connectedParts[i].connectionType +" -> ("+(HexMetrics.Direction)i+") " + physicalConnections[i]);
			SetPhysicalConnection((HexMetrics.Direction)i, physicalConnections[i], SplitOptions.DoNotSplit);
			SetAuxilaryConnections((HexMetrics.Direction)i, auxilaryConnections[i]);
			
		}
		
		if (ParentConstruction != null)
		{
			return ParentConstruction.CheckForSplitsOrJoins();
		}
		return new HashSet<Construction>();
	}
Esempio n. 53
0
		public GrabberState(HexMetrics.Direction dir, int ext, bool clampOpen)
		{
			direction = dir;
			extention = ext;
			this.clampOpen = clampOpen;
			rotation = 0;
		}
	public int SimulationRotationDifference(HexMetrics.Direction other)
	{
		return RotationDifference(SimulationOrientation, other);
	}
	public IEnumerable<HexMetrics.Direction> IsWeldableWithRotationFactor (HexMetrics.Direction relativeDirection, GrabbablePart otherPart)
	{
		for (int i = 0 ; i < 6 ; i++)
		{
			HexMetrics.Direction iDir = (HexMetrics.Direction)i;
			if (IsWeldable(relativeDirection, otherPart, iDir))
			{
				yield return iDir;
			}
		}
	}
	public HexMetrics.Direction OtherPartsOppositeDirection(HexMetrics.Direction relativeDirection, GrabbablePart otherPart)
	{
		return ReverseDirection( otherPart.RelativeDirectionFromAbsolute(AbsoluteDirectionFromRelative(relativeDirection)));
	}
	public bool IsWeldable (HexMetrics.Direction relativeDirection, GrabbablePart otherPart)
	{
		return IsWeldable(relativeDirection, otherPart, (HexMetrics.Direction)0);
	}
	public bool IsWeldable (HexMetrics.Direction relativeDirection, GrabbablePart otherPart, HexMetrics.Direction rotationFactor)
	{
//		relativeDirection = (HexMetrics.Direction)(((int)relativeDirection+(int)rotationFactor+6)%6);
		
		if (otherPart == null) return false;
		
		HexMetrics.Direction oppositeDirection = OtherPartsOppositeDirection(relativeDirection, otherPart);
		oppositeDirection = (HexMetrics.Direction)(((int)oppositeDirection+(int)rotationFactor+6)%6); // what if we were to rotate the other part?
//		ConnectionDescription otherConnDesc = connDesc.connectedPart._connectedParts[(int)oppositeDirection];
		
		bool weldableHere = Weldable(relativeDirection);
		bool weldabelThere = otherPart.Weldable(oppositeDirection);
//		Debug.Log("Checking weldability: "+direction+"("+weldableHere+") <-> "+oppositeDirection+"("+weldabelThere+")");
		
		return weldableHere && weldabelThere;
	}
	public GrabbablePart RemoveConnectedPart(HexMetrics.Direction relativeDirection)
	{
		GrabbablePart ret = _connectedParts[(int)relativeDirection].connectedPart;
		
//		if ( transform.parent != null && ret != null && ret.transform == transform.parent )
//		{
//			transform.parent = null;
//		}
		_connectedParts[(int)relativeDirection].connectedPart = null;
		_connectedParts[(int)relativeDirection].connectionType = PhysicalConnectionType.None;
		_connectedParts[(int)relativeDirection].auxConnectionTypes = 0;
		
		return ret;
	}
	public HexMetrics.Direction Relative(HexMetrics.Direction absoluteDirection)
	{
		return RelativeDirectionFromAbsolute(absoluteDirection);
	}