Ejemplo n.º 1
0
        Tile OrientTile(Tile toPlace, Tile.Edge matchingEdge, Tile.Edge toMatch)
        {
            while (true)
            {
                if (CurrentEdge(toMatch, toPlace).Checksum == toMatch.Checksum)
                {
                    return(toPlace);
                }

                toPlace = toPlace.Rotate();
                if (CurrentEdge(toMatch, toPlace).Checksum == toMatch.Checksum)
                {
                    return(toPlace);
                }

                var flipped = toMatch.Type == Tile.EdgeType.Bottom ? toPlace.FlipHorizontal() : toPlace.FlipVertical();
                if (CurrentEdge(toMatch, flipped).Checksum == toMatch.Checksum)
                {
                    return(flipped);
                }
            }

            Tile.Edge CurrentEdge(Tile.Edge toMatch, Tile toPlace) =>
            toMatch.Type == Tile.EdgeType.Bottom ? toPlace.TopEdge() : toPlace.LeftEdge();
        }
Ejemplo n.º 2
0
    private void SetNeihbors(ref Dictionary <Tile.Edge, List <Tile> > edgeToTriangeDic, Tile.Edge edge, Tile tile)
    {
        if (edgeToTriangeDic.ContainsKey(edge))
        {
            var list = edgeToTriangeDic[edge];

            for (int i = 0; i < list.Count; ++i)
            {
                if (list[i].neihbors.ContainsKey(edge) == false)
                {
                    list[i].neihbors.Add(edge, tile);
                }

                if (tile.neihbors.ContainsKey(edge) == false)
                {
                    tile.neihbors.Add(edge, list[i]);
                }
            }
            list.Add(tile);
        }
        else
        {
            edgeToTriangeDic.Add(edge, new List <Tile>());
            edgeToTriangeDic[edge].Add(tile);
        }
    }
Ejemplo n.º 3
0
    /// <summary>
    /// 初始化球形三角网格
    /// </summary>
    /// <param name="radius">球形半径</param>
    /// <param name="recursion">递归细分次数</param>
    public void Init(float radius, int recursion)
    {
        this.radius    = radius;
        this.recursion = recursion;

        if (recursion < 1)
        {
            recursion = 1;
        }

        List <Vector3>         vertList = new List <Vector3>();
        Dictionary <long, int> middlePointIndexCache = new Dictionary <long, int>();

        // create 12 vertices of a icosahedron
        float t = (1f + Mathf.Sqrt(5f)) / 2f;

        vertList.Add(new Vector3(-1f, t, 0f).normalized *radius);
        vertList.Add(new Vector3(1f, t, 0f).normalized *radius);
        vertList.Add(new Vector3(-1f, -t, 0f).normalized *radius);
        vertList.Add(new Vector3(1f, -t, 0f).normalized *radius);

        vertList.Add(new Vector3(0f, -1f, t).normalized *radius);
        vertList.Add(new Vector3(0f, 1f, t).normalized *radius);
        vertList.Add(new Vector3(0f, -1f, -t).normalized *radius);
        vertList.Add(new Vector3(0f, 1f, -t).normalized *radius);

        vertList.Add(new Vector3(t, 0f, -1f).normalized *radius);
        vertList.Add(new Vector3(t, 0f, 1f).normalized *radius);
        vertList.Add(new Vector3(-t, 0f, -1f).normalized *radius);
        vertList.Add(new Vector3(-t, 0f, 1f).normalized *radius);


        // create 20 triangles of the icosahedron
        List <TriangleIndices> faces  = new List <TriangleIndices>();
        List <TriangleIndices> faces2 = new List <TriangleIndices>();

        // 5 faces around point 0
        faces.Add(new TriangleIndices(null, new Vector3Int(0, 11, 5)));
        faces.Add(new TriangleIndices(null, new Vector3Int(0, 5, 1)));
        faces.Add(new TriangleIndices(null, new Vector3Int(0, 1, 7)));
        faces.Add(new TriangleIndices(null, new Vector3Int(0, 7, 10)));
        faces.Add(new TriangleIndices(null, new Vector3Int(0, 10, 11)));

        // 5 adjacent faces
        faces.Add(new TriangleIndices(null, new Vector3Int(1, 5, 9)));
        faces.Add(new TriangleIndices(null, new Vector3Int(5, 11, 4)));
        faces.Add(new TriangleIndices(null, new Vector3Int(11, 10, 2)));
        faces.Add(new TriangleIndices(null, new Vector3Int(10, 7, 6)));
        faces.Add(new TriangleIndices(null, new Vector3Int(7, 1, 8)));

        // 5 faces around point 3
        faces.Add(new TriangleIndices(null, new Vector3Int(3, 9, 4)));
        faces.Add(new TriangleIndices(null, new Vector3Int(3, 4, 2)));
        faces.Add(new TriangleIndices(null, new Vector3Int(3, 2, 6)));
        faces.Add(new TriangleIndices(null, new Vector3Int(3, 6, 8)));
        faces.Add(new TriangleIndices(null, new Vector3Int(3, 8, 9)));

        // 5 adjacent faces
        faces.Add(new TriangleIndices(null, new Vector3Int(4, 9, 5)));
        faces.Add(new TriangleIndices(null, new Vector3Int(2, 4, 11)));
        faces.Add(new TriangleIndices(null, new Vector3Int(6, 2, 10)));
        faces.Add(new TriangleIndices(null, new Vector3Int(8, 6, 7)));
        faces.Add(new TriangleIndices(null, new Vector3Int(9, 8, 1)));


        roots = new List <Tile>();

        // refine triangles
        for (int i = 0; i < recursion; i++)
        {
            faces2.Clear();
            foreach (var face in faces)
            {
                Tile tile = null;
                if (face.tile == null)
                {
                    tile = new Tile(this, null,
                                    vertList[face.index.x],
                                    vertList[face.index.y],
                                    vertList[face.index.z]);

                    tile.index = roots.Count;
                    tile.depth = i;

                    roots.Add(tile);
                }
                else
                {
                    tile = new Tile(this, face.tile,
                                    vertList[face.index.x],
                                    vertList[face.index.y],
                                    vertList[face.index.z]);

                    tile.index = face.tile.index * 10 + face.tile.children.Count;
                    tile.depth = i;

                    face.tile.children.Add(tile);
                }

                // replace triangle by 4 triangles
                int a = GetMiddlePoint(face.index.x, face.index.y, ref vertList, ref middlePointIndexCache, radius);
                int b = GetMiddlePoint(face.index.y, face.index.z, ref vertList, ref middlePointIndexCache, radius);
                int c = GetMiddlePoint(face.index.z, face.index.x, ref vertList, ref middlePointIndexCache, radius);

                faces2.Add(new TriangleIndices(tile, new Vector3Int(face.index.x, a, c)));
                faces2.Add(new TriangleIndices(tile, new Vector3Int(face.index.y, b, a)));
                faces2.Add(new TriangleIndices(tile, new Vector3Int(face.index.z, c, b)));
                faces2.Add(new TriangleIndices(tile, new Vector3Int(a, b, c)));
            }

            var temp = faces;
            faces  = faces2;
            faces2 = temp;
        }

        Dictionary <Tile.Edge, List <Tile> > segmentToTriangeDic = new Dictionary <Tile.Edge, List <Tile> >();
        Dictionary <Vector3, List <Tile> >   pointToTriangeDic   = new Dictionary <Vector3, List <Tile> >();

        for (int i = 0; i < faces.Count; ++i)
        {
            var tri = faces[i];
            if (tilesType.Count == 0 || (tilesType.Count > 0 && tilesType.ContainsKey(i)))
            {
                var tile = new Tile(this, tri.tile,
                                    vertList[tri.index.x],
                                    vertList[tri.index.y],
                                    vertList[tri.index.z]);

                tiles.Add(tile);
                if (tri.tile != null)
                {
                    tile.index = i;
                    tile.depth = tri.tile.depth + 1;
                    tri.tile.children.Add(tile);
                }

                Tile.Edge ab = new Tile.Edge(tile.a, tile.b);
                Tile.Edge ac = new Tile.Edge(tile.a, tile.c);
                Tile.Edge bc = new Tile.Edge(tile.b, tile.c);

                SetNeihbors(ref segmentToTriangeDic, ab, tile);
                SetNeihbors(ref segmentToTriangeDic, ac, tile);
                SetNeihbors(ref segmentToTriangeDic, bc, tile);

                SetCorners(ref pointToTriangeDic, tile.a, tile);
                SetCorners(ref pointToTriangeDic, tile.b, tile);
                SetCorners(ref pointToTriangeDic, tile.c, tile);
            }
        }

        RemoveEmpty(roots);
    }