Exemple #1
0
    private void Move(Direction direction)
    {
        CellEdge edge = currentCell.GetEdge(direction);

        if (edge is DungeonPassage)
        {
            SetLocation(edge.otherCell);
        }
    }
Exemple #2
0
 private CellEdge getOrAdd(CellEdge c, Dictionary <String, CellEdge> dic)
 {
     if (dic.ContainsKey(c.name))
     {
         return(dic[c.name]);
     }
     else
     {
         dic.Add(c.name, c);
         return(dic[c.name]);
     }
 }
 private void DrawGraphEdge(CellEdge edge, Color c, int thickness, bool trueForVoronoi)
 {
     if (trueForVoronoi)
     {
         Vector2Int pos0 = MapGraphCoordToTextureCoords(edge.v0.position.x, edge.v0.position.y);
         Vector2Int pos1 = MapGraphCoordToTextureCoords(edge.v1.position.x, edge.v1.position.y);
         DrawLine(pos0.x, pos0.y, pos1.x, pos1.y, thickness, c);
     }
     else
     {
         Vector2Int pos0 = MapGraphCoordToTextureCoords(edge.d0.position.x, edge.d0.position.y);
         Vector2Int pos1 = MapGraphCoordToTextureCoords(edge.d1.position.x, edge.d1.position.y);
         DrawLine(pos0.x, pos0.y, pos1.x, pos1.y, thickness, c);
     }
 }
Exemple #4
0
 public void SetEdge(Direction dir, CellEdge edge)
 {
     edges[(int)dir]        = edge;
     iInitialisedEdgeCount += 1;
 }
Exemple #5
0
    public MeshData GenerateTerrainMesh(MapData mapData)
    {
        MeshData meshData = new MeshData();

        // per ogni spigolo del dizionario tira fuori i 4 punti centrali delle celle che lo condividono e collegali con 2 triangolis
        foreach (CellEdge edg in mapData.edgeDictionary.Values)
        {
            //crea i 2 triangoli su tutti gli spigoli che sono condivisi da almeno 4 celle di questo stesso chunk
            if (edg.cells[0] != Vector3.zero && edg.cells[1] != Vector3.zero &&
                edg.cells[2] != Vector3.zero && edg.cells[3] != Vector3.zero)
            {
                if (edg.isFlipped)
                {
                    meshData.AddTriangle(
                        edg.cells[0],
                        edg.cells[2],
                        edg.cells[1],
                        MeshData.TYPE_NORMAL
                        );
                    meshData.AddTriangle(
                        edg.cells[2],
                        edg.cells[3],
                        edg.cells[1],
                        MeshData.TYPE_NORMAL
                        );
                }
                else
                {
                    meshData.AddTriangle(
                        edg.cells[0],
                        edg.cells[1],
                        edg.cells[2],
                        MeshData.TYPE_NORMAL
                        );
                    meshData.AddTriangle(
                        edg.cells[2],
                        edg.cells[1],
                        edg.cells[3],
                        MeshData.TYPE_NORMAL
                        );
                }
            }
            else
            {
                //X+ patches
                if (mapData.edgeDictionaryXPlusNormalPatch.ContainsKey(edg.name))
                {
                    CellEdge patch = new CellEdge(edg.inV, edg.outV, edg.noiseIn, edg.noiseOut, edg.position, edg.treshold);

                    if (edg.cells[0] == Vector3.zero && edg.cells[1] == Vector3.zero &&
                        edg.cells[2] != Vector3.zero && edg.cells[3] != Vector3.zero
                        )
                    {
                        if (!edg.isFlipped)
                        {
                            meshData.AddTriangle(
                                mapData.edgeDictionaryXPlusNormalPatch[edg.name].cells[1],
                                edg.cells[3],
                                edg.cells[2],
                                MeshData.TYPE_X_NORMAL_PLUS
                                );
                            meshData.AddTriangle(
                                mapData.edgeDictionaryXPlusNormalPatch[edg.name].cells[0],
                                mapData.edgeDictionaryXPlusNormalPatch[edg.name].cells[1],
                                edg.cells[2],
                                MeshData.TYPE_X_NORMAL_PLUS
                                );
                        }
                        else
                        {
                            meshData.AddTriangle(
                                mapData.edgeDictionaryXPlusNormalPatch[edg.name].cells[1],
                                edg.cells[2],
                                edg.cells[3],
                                MeshData.TYPE_X_NORMAL_PLUS
                                );
                            meshData.AddTriangle(
                                mapData.edgeDictionaryXPlusNormalPatch[edg.name].cells[1],
                                mapData.edgeDictionaryXPlusNormalPatch[edg.name].cells[0],
                                edg.cells[2],
                                MeshData.TYPE_X_NORMAL_PLUS
                                );
                        }
                    }
                    else
                    {
                        /*
                         * Debug.Log(" 0:"+ edg.cells[0].Equals(Vector3.zero)
                         + " 1:" + edg.cells[1].Equals(Vector3.zero)
                         + " 2:" + edg.cells[2].Equals(Vector3.zero)
                         + " 3:" + edg.cells[3].Equals(Vector3.zero)
                         +  );
                         */
                        //secondo giro di patch ? (se no fa una si e una no)
                        if (edg.cells[0] == Vector3.zero && edg.cells[2] == Vector3.zero &&
                            edg.cells[1] != Vector3.zero && edg.cells[3] != Vector3.zero
                            )
                        {
                            if (edg.isFlipped)
                            {
                                meshData.AddTriangle(
                                    mapData.edgeDictionaryXPlusNormalPatch[edg.name].cells[0],
                                    edg.cells[3],
                                    edg.cells[1],
                                    MeshData.TYPE_X_NORMAL_PLUS
                                    );

                                meshData.AddTriangle(
                                    mapData.edgeDictionaryXPlusNormalPatch[edg.name].cells[2],
                                    edg.cells[3],
                                    mapData.edgeDictionaryXPlusNormalPatch[edg.name].cells[0],
                                    MeshData.TYPE_X_NORMAL_PLUS
                                    );
                            }
                            else
                            {
                                meshData.AddTriangle(
                                    mapData.edgeDictionaryXPlusNormalPatch[edg.name].cells[0],
                                    edg.cells[1],
                                    edg.cells[3],
                                    MeshData.TYPE_X_NORMAL_PLUS
                                    );
                                meshData.AddTriangle(
                                    mapData.edgeDictionaryXPlusNormalPatch[edg.name].cells[2],
                                    mapData.edgeDictionaryXPlusNormalPatch[edg.name].cells[0],
                                    edg.cells[3],
                                    MeshData.TYPE_X_NORMAL_PLUS
                                    );
                            }
                        }

                        //celletta angolo X+ Y+

                        if (
                            edg.cells[0] == Vector3.zero &&
                            edg.cells[1] == Vector3.zero &&
                            edg.cells[2] == Vector3.zero &&
                            edg.cells[3] != Vector3.zero
                            )
                        {
                            meshData.AddTriangle(
                                // mapData.edgeDictionaryXPlusNormalPatch[edg.name].cells[3],
                                // mapData.edgeDictionaryXPlusNormalPatch[edg.name].cells[2],
                                edg.cells[3],
                                // edg.cells[3] + new Vector3(80, 80, 0),
                                mapData.edgeDictionaryXPlusNormalPatch[edg.name].cells[0],
                                mapData.edgeDictionaryXPlusNormalPatch[edg.name].cells[2],
                                MeshData.TYPE_X_NORMAL_PLUS
                                //

                                );
                        }
                    }
                }


                ///////

                /*
                 * //Y+ patches
                 * if (mapData.edgeDictionaryYPlusNormalPatch.ContainsKey(edg.name)) {
                 *
                 *  CellEdge patch = new CellEdge(edg.inV, edg.outV, edg.noiseIn, edg.noiseOut, edg.position, edg.treshold);
                 *
                 *  if (edg.cells[0] == Vector3.zero && edg.cells[1] == Vector3.zero
                 *      && edg.cells[2] != Vector3.zero && edg.cells[3] != Vector3.zero
                 *      ) {
                 *
                 *      if (!edg.isFlipped) {
                 *
                 *          meshData.AddTriangle(
                 *                     mapData.edgeDictionaryYPlusNormalPatch[edg.name].cells[1],
                 *                      edg.cells[3],
                 *                      edg.cells[2]
                 *                      );
                 *          meshData.AddTriangle(
                 *                    mapData.edgeDictionaryYPlusNormalPatch[edg.name].cells[0],
                 *                    mapData.edgeDictionaryYPlusNormalPatch[edg.name].cells[1],
                 *                     edg.cells[2]
                 *                     );
                 *
                 *      } else {
                 *
                 *          meshData.AddTriangle(
                 *                   mapData.edgeDictionaryYPlusNormalPatch[edg.name].cells[1],
                 *                   edg.cells[2],
                 *                   edg.cells[3]
                 *                   );
                 *          meshData.AddTriangle(
                 *                   mapData.edgeDictionaryYPlusNormalPatch[edg.name].cells[1],
                 *                   mapData.edgeDictionaryYPlusNormalPatch[edg.name].cells[0],
                 *                    edg.cells[2]
                 *                    );
                 *      }
                 *  }
                 * }
                 */
                ///////

                // addNormalPatchTriangles(meshData, edg, mapData.edgeDictionaryXPlusNormalPatch);
                //addNormalPatchTriangles(meshData, edg, mapData.edgeDictionaryYPlusNormalPatch);
                // addNormalPatchTriangles(meshData, edg, mapData.edgeDictionaryZPlusNormalPatch);
            }
        }
        return(meshData);
    }
Exemple #6
0
    public MapData GenerateTerrainData(float size, int subdivisions, Vector3 position, CustomImprovedNoise noise,
                                       Dictionary <string, CellEdge> edgeDictionary,
                                       Dictionary <string, CellEdge> edgeDictionaryXPlusNormalPatch,
                                       Dictionary <string, CellEdge> edgeDictionaryYPlusNormalPatch,
                                       Dictionary <string, CellEdge> edgeDictionaryZPlusNormalPatch
                                       )
    {
        this.position = position;

        float increment = size / subdivisions;

        int flagIndex = 0;
        //float treshold = 0.4f;
        float   treshold = DCManager.radius * 0.55f;
        Vector3 centerPoint;
        int     i, x, y, z;

        Vector3[]       edgeVertex;
        List <CellEdge> edgeList = new List <CellEdge>();
        int             numEdgesWithIntersections = 0;

        MapData mapData = new MapData();

        Vector3[] cube;
        float[]   noiseCube;


        // spigoli interni
        for (x = 0; x < subdivisions; x++)
        {
            for (y = 0; y < subdivisions; y++)
            {
                for (z = 0; z < subdivisions; z++)
                {
                    edgeList.Clear();
                    cube       = new Vector3[8];
                    noiseCube  = new float[8];
                    edgeVertex = new Vector3[12];


                    numEdgesWithIntersections = 0;
                    flagIndex = 0;

                    Vector3 v0 = new Vector3(-size / 2 + x * increment, -size / 2 + y * increment, -size / 2 + z * increment);
                    Vector3 v1 = new Vector3(-size / 2 + x * increment, -size / 2 + y * increment, -size / 2 + z * increment + increment);
                    Vector3 v2 = new Vector3(-size / 2 + x * increment + increment, -size / 2 + y * increment, -size / 2 + z * increment + increment);
                    Vector3 v3 = new Vector3(-size / 2 + x * increment + increment, -size / 2 + y * increment, -size / 2 + z * increment);

                    Vector3 v4 = new Vector3(-size / 2 + x * increment, -size / 2 + y * increment + increment, -size / 2 + z * increment);
                    Vector3 v5 = new Vector3(-size / 2 + x * increment, -size / 2 + y * increment + increment, -size / 2 + z * increment + increment);
                    Vector3 v6 = new Vector3(-size / 2 + x * increment + increment, -size / 2 + y * increment + increment, -size / 2 + z * increment + increment);
                    Vector3 v7 = new Vector3(-size / 2 + x * increment + increment, -size / 2 + y * increment + increment, -size / 2 + z * increment);

                    cube[0] = v0;
                    cube[1] = v1;
                    cube[2] = v2;
                    cube[3] = v3;
                    cube[4] = v4;
                    cube[5] = v5;
                    cube[6] = v6;
                    cube[7] = v7;



                    for (i = 0; i < 8; i++)
                    {
                        noiseCube[i] = DCManager.radius - (cube[i] + position).magnitude;

                        if (noiseCube[i] <= treshold)
                        {
                            flagIndex |= 1 << i;
                        }
                    }

                    if (flagIndex == 0 || flagIndex == 255)
                    {
                        continue;
                    }


                    // prepara gli spigoli e ordinali in un dizionario
                    edgeList.Add(new CellEdge(v0, v1, noiseCube[0], noiseCube[1], position, treshold));
                    edgeList.Add(new CellEdge(v2, v3, noiseCube[2], noiseCube[3], position, treshold));
                    edgeList.Add(new CellEdge(v4, v5, noiseCube[4], noiseCube[5], position, treshold));
                    edgeList.Add(new CellEdge(v6, v7, noiseCube[6], noiseCube[7], position, treshold));

                    edgeList.Add(new CellEdge(v1, v5, noiseCube[1], noiseCube[5], position, treshold));
                    edgeList.Add(new CellEdge(v0, v4, noiseCube[0], noiseCube[4], position, treshold));
                    edgeList.Add(new CellEdge(v2, v6, noiseCube[2], noiseCube[6], position, treshold));
                    edgeList.Add(new CellEdge(v3, v7, noiseCube[3], noiseCube[7], position, treshold));

                    edgeList.Add(new CellEdge(v0, v3, noiseCube[0], noiseCube[3], position, treshold));
                    edgeList.Add(new CellEdge(v1, v2, noiseCube[1], noiseCube[2], position, treshold));
                    edgeList.Add(new CellEdge(v4, v7, noiseCube[4], noiseCube[7], position, treshold));
                    edgeList.Add(new CellEdge(v5, v6, noiseCube[5], noiseCube[6], position, treshold));


                    // per ogni cubo trova quanti spigoli hanno intersezioni
                    numEdgesWithIntersections = 0;
                    centerPoint = new Vector3();
                    foreach (CellEdge ce in edgeList)
                    {
                        if (ce.hasIntersection)
                        {
                            CellEdge c = getOrAdd(ce, edgeDictionary);
                            numEdgesWithIntersections++;
                            centerPoint += ce.intersectionPoint;
                        }
                    }
                    if (numEdgesWithIntersections == 0 || numEdgesWithIntersections == 8)
                    {
                        continue;
                    }
                    centerPoint = centerPoint / numEdgesWithIntersections;

                    // ora che sappiamo quanti spigoli hanno intersezioni calcola il punto medio tra loro e settalo come punto centrale della cella
                    // dual contour - per infighettarlo qua dovresti applicare la QEF, invece del punto medio tra gli spigoli che hanno intersezioni
                    int k = 0;
                    foreach (CellEdge ce in edgeList)
                    {
                        if (ce.hasIntersection)
                        {
                            CellEdge c = getOrAdd(ce, edgeDictionary);
                            c.cells[k] = centerPoint;
                        }
                        k++;
                        if (k > 3)
                        {
                            k = 0;
                        }
                    }
                }
            }
        } // fine del mega ciclo


        ///////////////

        // spigoli esterni X+
        for (x = subdivisions; x < subdivisions + 1; x++)
        {
            for (y = 0; y < subdivisions + 1; y++)
            {
                for (z = 0; z < subdivisions + 1; z++)
                {
                    edgeList.Clear();
                    cube       = new Vector3[8];
                    noiseCube  = new float[8];
                    edgeVertex = new Vector3[12];


                    numEdgesWithIntersections = 0;
                    flagIndex = 0;

                    Vector3 v0 = new Vector3(-size / 2 + x * increment, -size / 2 + y * increment, -size / 2 + z * increment);
                    Vector3 v1 = new Vector3(-size / 2 + x * increment, -size / 2 + y * increment, -size / 2 + z * increment + increment);
                    Vector3 v2 = new Vector3(-size / 2 + x * increment + increment, -size / 2 + y * increment, -size / 2 + z * increment + increment);
                    Vector3 v3 = new Vector3(-size / 2 + x * increment + increment, -size / 2 + y * increment, -size / 2 + z * increment);

                    Vector3 v4 = new Vector3(-size / 2 + x * increment, -size / 2 + y * increment + increment, -size / 2 + z * increment);
                    Vector3 v5 = new Vector3(-size / 2 + x * increment, -size / 2 + y * increment + increment, -size / 2 + z * increment + increment);
                    Vector3 v6 = new Vector3(-size / 2 + x * increment + increment, -size / 2 + y * increment + increment, -size / 2 + z * increment + increment);
                    Vector3 v7 = new Vector3(-size / 2 + x * increment + increment, -size / 2 + y * increment + increment, -size / 2 + z * increment);

                    cube[0] = v0;
                    cube[1] = v1;
                    cube[2] = v2;
                    cube[3] = v3;
                    cube[4] = v4;
                    cube[5] = v5;
                    cube[6] = v6;
                    cube[7] = v7;



                    for (i = 0; i < 8; i++)
                    {
                        noiseCube[i] = DCManager.radius - (cube[i] + position).magnitude;

                        if (noiseCube[i] <= treshold)
                        {
                            flagIndex |= 1 << i;                             // flagIndex = flagIndex | 1<<i
                        }
                        //if(cube[i])
                    }

                    if (flagIndex == 0 || flagIndex == 255)
                    {
                        continue;
                    }


                    // prepara gli spigoli e ordinali in un dizionario
                    edgeList.Add(new CellEdge(v0, v1, noiseCube[0], noiseCube[1], position, treshold));
                    edgeList.Add(new CellEdge(v2, v3, noiseCube[2], noiseCube[3], position, treshold));
                    edgeList.Add(new CellEdge(v4, v5, noiseCube[4], noiseCube[5], position, treshold));
                    edgeList.Add(new CellEdge(v6, v7, noiseCube[6], noiseCube[7], position, treshold));

                    edgeList.Add(new CellEdge(v1, v5, noiseCube[1], noiseCube[5], position, treshold));
                    edgeList.Add(new CellEdge(v0, v4, noiseCube[0], noiseCube[4], position, treshold));
                    edgeList.Add(new CellEdge(v2, v6, noiseCube[2], noiseCube[6], position, treshold));
                    edgeList.Add(new CellEdge(v3, v7, noiseCube[3], noiseCube[7], position, treshold));

                    edgeList.Add(new CellEdge(v0, v3, noiseCube[0], noiseCube[3], position, treshold));
                    edgeList.Add(new CellEdge(v1, v2, noiseCube[1], noiseCube[2], position, treshold));
                    edgeList.Add(new CellEdge(v4, v7, noiseCube[4], noiseCube[7], position, treshold));
                    edgeList.Add(new CellEdge(v5, v6, noiseCube[5], noiseCube[6], position, treshold));


                    // per ogni cubo trova quanti spigoli hanno intersezioni
                    numEdgesWithIntersections = 0;
                    centerPoint = new Vector3();
                    foreach (CellEdge ce in edgeList)
                    {
                        if (ce.hasIntersection)
                        {
                            CellEdge c = getOrAdd(ce, edgeDictionaryXPlusNormalPatch);
                            numEdgesWithIntersections++;
                            centerPoint += ce.intersectionPoint;
                        }
                    }
                    if (numEdgesWithIntersections == 0 || numEdgesWithIntersections == 8)
                    {
                        continue;
                    }
                    centerPoint = centerPoint / numEdgesWithIntersections;

                    // ora che sappiamo quanti spigoli hanno intersezioni calcola il punto medio tra loro e settalo come punto centrale della cella
                    // dual contour - per infighettarlo qua dovresti applicare la QEF, invece del punto medio tra gli spigoli che hanno intersezioni
                    int k = 0;
                    foreach (CellEdge ce in edgeList)
                    {
                        if (ce.hasIntersection)
                        {
                            CellEdge c = getOrAdd(ce, edgeDictionaryXPlusNormalPatch);
                            c.cells[k] = centerPoint;
                        }
                        k++;
                        if (k > 3)
                        {
                            k = 0;
                        }
                    }
                }
            }
        }

        /////////////////

        // spigoli esterni Y+
        for (x = 0; x < subdivisions; x++)
        {
            for (y = subdivisions; y < subdivisions + 1; y++)
            {
                for (z = 0; z < subdivisions; z++)
                {
                    edgeList.Clear();
                    cube       = new Vector3[8];
                    noiseCube  = new float[8];
                    edgeVertex = new Vector3[12];


                    numEdgesWithIntersections = 0;
                    flagIndex = 0;

                    Vector3 v0 = new Vector3(-size / 2 + x * increment, -size / 2 + y * increment, -size / 2 + z * increment);
                    Vector3 v1 = new Vector3(-size / 2 + x * increment, -size / 2 + y * increment, -size / 2 + z * increment + increment);
                    Vector3 v2 = new Vector3(-size / 2 + x * increment + increment, -size / 2 + y * increment, -size / 2 + z * increment + increment);
                    Vector3 v3 = new Vector3(-size / 2 + x * increment + increment, -size / 2 + y * increment, -size / 2 + z * increment);

                    Vector3 v4 = new Vector3(-size / 2 + x * increment, -size / 2 + y * increment + increment, -size / 2 + z * increment);
                    Vector3 v5 = new Vector3(-size / 2 + x * increment, -size / 2 + y * increment + increment, -size / 2 + z * increment + increment);
                    Vector3 v6 = new Vector3(-size / 2 + x * increment + increment, -size / 2 + y * increment + increment, -size / 2 + z * increment + increment);
                    Vector3 v7 = new Vector3(-size / 2 + x * increment + increment, -size / 2 + y * increment + increment, -size / 2 + z * increment);

                    cube[0] = v0;
                    cube[1] = v1;
                    cube[2] = v2;
                    cube[3] = v3;
                    cube[4] = v4;
                    cube[5] = v5;
                    cube[6] = v6;
                    cube[7] = v7;



                    for (i = 0; i < 8; i++)
                    {
                        noiseCube[i] = DCManager.radius - (cube[i] + position).magnitude;

                        if (noiseCube[i] <= treshold)
                        {
                            flagIndex |= 1 << i;                             // flagIndex = flagIndex | 1<<i
                        }
                        //if(cube[i])
                    }

                    if (flagIndex == 0 || flagIndex == 255)
                    {
                        continue;
                    }


                    // prepara gli spigoli e ordinali in un dizionario
                    edgeList.Add(new CellEdge(v0, v1, noiseCube[0], noiseCube[1], position, treshold));
                    edgeList.Add(new CellEdge(v2, v3, noiseCube[2], noiseCube[3], position, treshold));
                    edgeList.Add(new CellEdge(v4, v5, noiseCube[4], noiseCube[5], position, treshold));
                    edgeList.Add(new CellEdge(v6, v7, noiseCube[6], noiseCube[7], position, treshold));

                    edgeList.Add(new CellEdge(v1, v5, noiseCube[1], noiseCube[5], position, treshold));
                    edgeList.Add(new CellEdge(v0, v4, noiseCube[0], noiseCube[4], position, treshold));
                    edgeList.Add(new CellEdge(v2, v6, noiseCube[2], noiseCube[6], position, treshold));
                    edgeList.Add(new CellEdge(v3, v7, noiseCube[3], noiseCube[7], position, treshold));

                    edgeList.Add(new CellEdge(v0, v3, noiseCube[0], noiseCube[3], position, treshold));
                    edgeList.Add(new CellEdge(v1, v2, noiseCube[1], noiseCube[2], position, treshold));
                    edgeList.Add(new CellEdge(v4, v7, noiseCube[4], noiseCube[7], position, treshold));
                    edgeList.Add(new CellEdge(v5, v6, noiseCube[5], noiseCube[6], position, treshold));


                    // per ogni cubo trova quanti spigoli hanno intersezioni
                    numEdgesWithIntersections = 0;
                    centerPoint = new Vector3();
                    foreach (CellEdge ce in edgeList)
                    {
                        if (ce.hasIntersection)
                        {
                            CellEdge c = getOrAdd(ce, edgeDictionaryYPlusNormalPatch);
                            numEdgesWithIntersections++;
                            centerPoint += ce.intersectionPoint;
                        }
                    }
                    if (numEdgesWithIntersections == 0 || numEdgesWithIntersections == 8)
                    {
                        continue;
                    }
                    centerPoint = centerPoint / numEdgesWithIntersections;

                    // ora che sappiamo quanti spigoli hanno intersezioni calcola il punto medio tra loro e settalo come punto centrale della cella
                    // dual contour - per infighettarlo qua dovresti applicare la QEF, invece del punto medio tra gli spigoli che hanno intersezioni
                    int k = 0;
                    foreach (CellEdge ce in edgeList)
                    {
                        if (ce.hasIntersection)
                        {
                            CellEdge c = getOrAdd(ce, edgeDictionaryYPlusNormalPatch);
                            c.cells[k] = centerPoint;
                        }
                        k++;
                        if (k > 3)
                        {
                            k = 0;
                        }
                    }
                }
            }
        }

        /////////////////

        // spigoli esterni Z+
        for (x = 0; x < subdivisions; x++)
        {
            for (y = 0; y < subdivisions; y++)
            {
                for (z = subdivisions; z < subdivisions + 1; z++)
                {
                    edgeList.Clear();
                    cube       = new Vector3[8];
                    noiseCube  = new float[8];
                    edgeVertex = new Vector3[12];


                    numEdgesWithIntersections = 0;
                    flagIndex = 0;

                    Vector3 v0 = new Vector3(-size / 2 + x * increment, -size / 2 + y * increment, -size / 2 + z * increment);
                    Vector3 v1 = new Vector3(-size / 2 + x * increment, -size / 2 + y * increment, -size / 2 + z * increment + increment);
                    Vector3 v2 = new Vector3(-size / 2 + x * increment + increment, -size / 2 + y * increment, -size / 2 + z * increment + increment);
                    Vector3 v3 = new Vector3(-size / 2 + x * increment + increment, -size / 2 + y * increment, -size / 2 + z * increment);

                    Vector3 v4 = new Vector3(-size / 2 + x * increment, -size / 2 + y * increment + increment, -size / 2 + z * increment);
                    Vector3 v5 = new Vector3(-size / 2 + x * increment, -size / 2 + y * increment + increment, -size / 2 + z * increment + increment);
                    Vector3 v6 = new Vector3(-size / 2 + x * increment + increment, -size / 2 + y * increment + increment, -size / 2 + z * increment + increment);
                    Vector3 v7 = new Vector3(-size / 2 + x * increment + increment, -size / 2 + y * increment + increment, -size / 2 + z * increment);

                    cube[0] = v0;
                    cube[1] = v1;
                    cube[2] = v2;
                    cube[3] = v3;
                    cube[4] = v4;
                    cube[5] = v5;
                    cube[6] = v6;
                    cube[7] = v7;



                    for (i = 0; i < 8; i++)
                    {
                        noiseCube[i] = DCManager.radius - (cube[i] + position).magnitude;

                        if (noiseCube[i] <= treshold)
                        {
                            flagIndex |= 1 << i;                             // flagIndex = flagIndex | 1<<i
                        }
                        //if(cube[i])
                    }

                    if (flagIndex == 0 || flagIndex == 255)
                    {
                        continue;
                    }


                    // prepara gli spigoli e ordinali in un dizionario
                    edgeList.Add(new CellEdge(v0, v1, noiseCube[0], noiseCube[1], position, treshold));
                    edgeList.Add(new CellEdge(v2, v3, noiseCube[2], noiseCube[3], position, treshold));
                    edgeList.Add(new CellEdge(v4, v5, noiseCube[4], noiseCube[5], position, treshold));
                    edgeList.Add(new CellEdge(v6, v7, noiseCube[6], noiseCube[7], position, treshold));

                    edgeList.Add(new CellEdge(v1, v5, noiseCube[1], noiseCube[5], position, treshold));
                    edgeList.Add(new CellEdge(v0, v4, noiseCube[0], noiseCube[4], position, treshold));
                    edgeList.Add(new CellEdge(v2, v6, noiseCube[2], noiseCube[6], position, treshold));
                    edgeList.Add(new CellEdge(v3, v7, noiseCube[3], noiseCube[7], position, treshold));

                    edgeList.Add(new CellEdge(v0, v3, noiseCube[0], noiseCube[3], position, treshold));
                    edgeList.Add(new CellEdge(v1, v2, noiseCube[1], noiseCube[2], position, treshold));
                    edgeList.Add(new CellEdge(v4, v7, noiseCube[4], noiseCube[7], position, treshold));
                    edgeList.Add(new CellEdge(v5, v6, noiseCube[5], noiseCube[6], position, treshold));


                    // per ogni cubo trova quanti spigoli hanno intersezioni
                    numEdgesWithIntersections = 0;
                    centerPoint = new Vector3();
                    foreach (CellEdge ce in edgeList)
                    {
                        if (ce.hasIntersection)
                        {
                            CellEdge c = getOrAdd(ce, edgeDictionaryZPlusNormalPatch);
                            numEdgesWithIntersections++;
                            centerPoint += ce.intersectionPoint;
                        }
                    }
                    if (numEdgesWithIntersections == 0 || numEdgesWithIntersections == 8)
                    {
                        continue;
                    }
                    centerPoint = centerPoint / numEdgesWithIntersections;

                    // ora che sappiamo quanti spigoli hanno intersezioni calcola il punto medio tra loro e settalo come punto centrale della cella
                    // dual contour - per infighettarlo qua dovresti applicare la QEF, invece del punto medio tra gli spigoli che hanno intersezioni
                    int k = 0;
                    foreach (CellEdge ce in edgeList)
                    {
                        if (ce.hasIntersection)
                        {
                            CellEdge c = getOrAdd(ce, edgeDictionaryZPlusNormalPatch);
                            c.cells[k] = centerPoint;
                        }
                        k++;
                        if (k > 3)
                        {
                            k = 0;
                        }
                    }
                }
            }
        }

        /////////////////


        mapData.edgeDictionary = edgeDictionary;
        mapData.edgeDictionaryXPlusNormalPatch = edgeDictionaryXPlusNormalPatch;
        //mapData.edgeDictionaryYPlusNormalPatch = edgeDictionaryYPlusNormalPatch;
        //mapData.edgeDictionaryZPlusNormalPatch = edgeDictionaryZPlusNormalPatch;


        return(mapData);
    }
Exemple #7
0
 public void SetEdge(Direction direction, CellEdge edge)
 {
     edges [(int)direction] = edge;
     edgeCount++;
 }
Exemple #8
0
 // sets the edge with the passed direction and cell edge and increases the initalised edge count
 public void setEdge(Direction direction, CellEdge edge)
 {
     edges[(int)direction] = edge;
     initialisedEdgeCount += 1;
 }
Exemple #9
0
	public void SetEdge (CellDirection direction, CellEdge edge) {
		edges[(int)direction] = edge;
	}
Exemple #10
0
    private void AssignElevations()
    {
        List <CellCorner> queue = new List <CellCorner>();       //We have to use a List<T> instead of a Queue<T> because we need to add itens both at the begging and a the end of the list
        float             minElevation = 1, maxElevation = 1;

        //Find all coast corners and assign their elevation to 0
        foreach (var corner in corners)
        {
            if (corner.isCoast)
            {
                queue.Add(corner);
                corner.elevation = 0;
            }
            else
            {
                corner.elevation = Mathf.Infinity;
            }
        }

        //Define some helper functions to help with the loop below
        bool IsCellLake(CellCenter c)
        {
            return(c.isWater && !c.isOcean);
        }

        bool IsEdgeLake(CellEdge e)
        {
            return(IsCellLake(e.d0) || IsCellLake(e.d1));
        }

        while (queue.Count > 0)
        {
            CellCorner currentCorner = queue[0];                              //Get the fisrt item on the list
            queue.RemoveAt(0);                                                //Remove the item from the list
            int offset = Random.Range(0, currentCorner.connectedEdges.Count); //Add a random offset to the iterator

            for (int i = 0; i < currentCorner.connectedEdges.Count; i++)
            {
                CellEdge   e            = currentCorner.connectedEdges[(i + offset) % currentCorner.connectedEdges.Count]; //uses the offset to start at a random edge, but still circulate through all of them
                CellCorner neighbor     = e.v0 == currentCorner ? e.v1 : e.v0;                                             //Get the corner that is part of this edge and opposite of the current corner
                float      newElevation = (IsEdgeLake(e) ? 0 : 1) + currentCorner.elevation;

                //If the neighboor has a higher elevation than the calculated one, we have to change the elevation (in other words, we always use the lowest calculated elevation value)
                if (newElevation < neighbor.elevation)
                {
                    neighbor.elevation       = newElevation;
                    neighbor.downslopeCorner = currentCorner;                     //Since this elevation is (corner elevation + (0 || 1)), that means this corner is either higher or the same height as the current corner, and so we can set the parent corner as the downslope
                    neighbor.downslopeEdge   = e;

                    //Update the min/max elevations
                    if (neighbor.isOcean && newElevation > minElevation)
                    {
                        minElevation = newElevation;
                    }

                    if (!neighbor.isOcean && newElevation > maxElevation)
                    {
                        maxElevation = newElevation;
                    }

                    //If this corner was a lake, we have to revisit it again to guarantee that all edges of a lake has the same elevation
                    if (IsEdgeLake(e))
                    {
                        queue.Insert(0, neighbor);
                    }
                    else
                    {
                        queue.Add(neighbor);
                    }
                }
            }
        }

        //Normalize the elevations so we have a range from 0 to 1 for land/lakes, and -1 to 0 for oceans
        foreach (var corner in corners)
        {
            if (!corner.isOcean)
            {
                corner.elevation = elevationCurve.Evaluate(corner.elevation / maxElevation);
            }
            else
            {
                corner.elevation = -elevationCurve.Evaluate(corner.elevation / minElevation);
            }
        }

        //Set the cell center elevation to be the average of its corners. Also, since the coastline is at elevation 0, if some ocean is greater than it, we override the value
        float maxOceanElevation = -0.01f;

        foreach (var center in cells)
        {
            float sumElevations = 0;

            foreach (var corner in center.cellCorners)
            {
                sumElevations += corner.elevation;
            }

            center.elevation = sumElevations / center.cellCorners.Count;

            //make sure that ocean cells won't be on a higher elevation than the coast
            if (center.isOcean && center.elevation > maxOceanElevation)
            {
                center.elevation = maxOceanElevation;
            }
        }
    }
Exemple #11
0
    private void GenerateGraphs(List <Vector2> points)
    {
        //Generate the Voronoi
        Rectf   bounds  = new Rectf(0, 0, size.x, size.y);
        Voronoi voronoi = new Voronoi(points, bounds, relaxation);

        //Cell centers
        foreach (var site in voronoi.SitesIndexedByLocation)
        {
            CellCenter c = new CellCenter();
            c.index    = cells.Count;
            c.position = site.Key;

            cells.Add(c);
        }

        //Cell Corners
        foreach (var edge in voronoi.Edges)
        {
            //If the edge doesn't have clipped ends, it was not withing bounds
            if (edge.ClippedEnds == null)
            {
                continue;
            }

            if (!corners.Any(x => x.position == edge.ClippedEnds[LR.LEFT]))
            {
                CellCorner c = new CellCorner();
                c.index    = corners.Count;
                c.position = edge.ClippedEnds[LR.LEFT];
                c.isBorder = c.position.x == 0 || c.position.x == size.x || c.position.y == 0 || c.position.y == size.y;

                corners.Add(c);
            }

            if (!corners.Any(x => x.position == edge.ClippedEnds[LR.RIGHT]))
            {
                CellCorner c = new CellCorner();
                c.index    = corners.Count;
                c.position = edge.ClippedEnds[LR.RIGHT];
                c.isBorder = c.position.x == 0 || c.position.x == size.x || c.position.y == 0 || c.position.y == size.y;

                corners.Add(c);
            }
        }

        //Define some local helper functions to help with the loop below
        void AddPointToPointList <T>(List <T> list, T point) where T : MapPoint
        {
            if (!list.Contains(point))
            {
                list.Add(point);
            }
        }

        //Voronoi and Delaunay edges. Each edge point to two cells and two corners, so we can store both the sites and corners into a single edge object (thus making two edges into one object)
        foreach (var voronoiEdge in voronoi.Edges)
        {
            if (voronoiEdge.ClippedEnds == null)
            {
                continue;
            }

            CellEdge edge = new CellEdge();
            edge.index = edges.Count;

            //Set the voronoi edge
            edge.v0 = corners.First(x => x.position == voronoiEdge.ClippedEnds[LR.LEFT]);
            edge.v1 = corners.First(x => x.position == voronoiEdge.ClippedEnds[LR.RIGHT]);

            //Set the Delaunay edge
            edge.d0 = cells.First(x => x.position == voronoiEdge.LeftSite.Coord);
            edge.d1 = cells.First(x => x.position == voronoiEdge.RightSite.Coord);

            edges.Add(edge);

            /*Set the relationships*/

            //Set the relationship between this edge and the connected cells centers/corners
            edge.d0.borderEdges.Add(edge);
            edge.d1.borderEdges.Add(edge);
            edge.v0.connectedEdges.Add(edge);
            edge.v1.connectedEdges.Add(edge);

            //Set the relationship between the CELL CENTERS connected to this edge
            AddPointToPointList(edge.d0.neighborCells, edge.d1);
            AddPointToPointList(edge.d1.neighborCells, edge.d0);

            //Set the relationship between the CORNERS connected to this edge
            AddPointToPointList(edge.v0.neighborCorners, edge.v1);
            AddPointToPointList(edge.v1.neighborCorners, edge.v0);

            //Set the relationship of the CORNERS connected to this edge and the CELL CENTERS connected to this edge
            AddPointToPointList(edge.d0.cellCorners, edge.v0);
            AddPointToPointList(edge.d0.cellCorners, edge.v1);

            AddPointToPointList(edge.d1.cellCorners, edge.v0);
            AddPointToPointList(edge.d1.cellCorners, edge.v1);

            //Same as above, but the other way around
            AddPointToPointList(edge.v0.touchingCells, edge.d0);
            AddPointToPointList(edge.v0.touchingCells, edge.d1);

            AddPointToPointList(edge.v1.touchingCells, edge.d0);
            AddPointToPointList(edge.v1.touchingCells, edge.d1);
        }
    }
Exemple #12
0
    public MapData GenerateTerrainData(float size, int subdivisions, Vector3 position, CustomImprovedNoise noise,
                                       Dictionary <string, CellEdge> edgeDictionary,
                                       Dictionary <string, CellEdge> edgeDictionaryOrphans

                                       )
    {
        this.position     = position;
        this.subdivisions = subdivisions;
        float increment = size / subdivisions;

        int flagIndex = 0;
        //float treshold = 0.4f;
        float   treshold = DCManager.radius * 0.55f;
        Vector3 centerPoint;
        int     i, x, y, z;

        Vector3[]       edgeVertex;
        List <CellEdge> edgeList = new List <CellEdge>();
        int             numEdgesWithIntersections = 0;

        MapData mapData = new MapData();

        Vector3[] cube;
        float[]   noiseCube;


        // trova gli spigoli che hanno intersezioni e dove: quando li trovi salvali in edgeDictionary
        // con nome [punto fuori + "|"+ punto dentro], valore la cellEdge(che contiene i 4 centerPoints)
        for (x = 0; x < subdivisions; x++)
        {
            for (y = 0; y < subdivisions; y++)
            {
                for (z = 0; z < subdivisions; z++)
                {
                    edgeList.Clear();
                    cube       = new Vector3[8];
                    noiseCube  = new float[8];
                    edgeVertex = new Vector3[12];


                    numEdgesWithIntersections = 0;
                    flagIndex = 0;

                    Vector3 v0 = new Vector3(-size / 2 + x * increment, -size / 2 + y * increment, -size / 2 + z * increment);
                    Vector3 v1 = new Vector3(-size / 2 + x * increment, -size / 2 + y * increment, -size / 2 + z * increment + increment);
                    Vector3 v2 = new Vector3(-size / 2 + x * increment + increment, -size / 2 + y * increment, -size / 2 + z * increment + increment);
                    Vector3 v3 = new Vector3(-size / 2 + x * increment + increment, -size / 2 + y * increment, -size / 2 + z * increment);

                    Vector3 v4 = new Vector3(-size / 2 + x * increment, -size / 2 + y * increment + increment, -size / 2 + z * increment);
                    Vector3 v5 = new Vector3(-size / 2 + x * increment, -size / 2 + y * increment + increment, -size / 2 + z * increment + increment);
                    Vector3 v6 = new Vector3(-size / 2 + x * increment + increment, -size / 2 + y * increment + increment, -size / 2 + z * increment + increment);
                    Vector3 v7 = new Vector3(-size / 2 + x * increment + increment, -size / 2 + y * increment + increment, -size / 2 + z * increment);

                    cube[0] = v0;
                    cube[1] = v1;
                    cube[2] = v2;
                    cube[3] = v3;
                    cube[4] = v4;
                    cube[5] = v5;
                    cube[6] = v6;
                    cube[7] = v7;



                    for (i = 0; i < 8; i++)
                    {
                        noiseCube[i] = DCManager.radius - (cube[i] + position).magnitude;

                        if (noiseCube[i] <= treshold)
                        {
                            flagIndex |= 1 << i;
                        }
                    }

                    if (flagIndex == 0 || flagIndex == 255)
                    {
                        continue;
                    }


                    // prepara gli spigoli e ordinali in un dizionario
                    edgeList.Add(new CellEdge(v0, v1, noiseCube[0], noiseCube[1], position, treshold)
                    {
                        px = x, py = y, pz = z
                    });
                    edgeList.Add(new CellEdge(v2, v3, noiseCube[2], noiseCube[3], position, treshold)
                    {
                        px = x, py = y, pz = z
                    });
                    edgeList.Add(new CellEdge(v4, v5, noiseCube[4], noiseCube[5], position, treshold)
                    {
                        px = x, py = y, pz = z
                    });
                    edgeList.Add(new CellEdge(v6, v7, noiseCube[6], noiseCube[7], position, treshold)
                    {
                        px = x, py = y, pz = z
                    });

                    edgeList.Add(new CellEdge(v1, v5, noiseCube[1], noiseCube[5], position, treshold)
                    {
                        px = x, py = y, pz = z
                    });
                    edgeList.Add(new CellEdge(v0, v4, noiseCube[0], noiseCube[4], position, treshold)
                    {
                        px = x, py = y, pz = z
                    });
                    edgeList.Add(new CellEdge(v2, v6, noiseCube[2], noiseCube[6], position, treshold)
                    {
                        px = x, py = y, pz = z
                    });
                    edgeList.Add(new CellEdge(v3, v7, noiseCube[3], noiseCube[7], position, treshold)
                    {
                        px = x, py = y, pz = z
                    });

                    edgeList.Add(new CellEdge(v0, v3, noiseCube[0], noiseCube[3], position, treshold)
                    {
                        px = x, py = y, pz = z
                    });
                    edgeList.Add(new CellEdge(v1, v2, noiseCube[1], noiseCube[2], position, treshold)
                    {
                        px = x, py = y, pz = z
                    });
                    edgeList.Add(new CellEdge(v4, v7, noiseCube[4], noiseCube[7], position, treshold)
                    {
                        px = x, py = y, pz = z
                    });
                    edgeList.Add(new CellEdge(v5, v6, noiseCube[5], noiseCube[6], position, treshold)
                    {
                        px = x, py = y, pz = z
                    });


                    // per ogni cubo trova quanti spigoli hanno intersezioni
                    numEdgesWithIntersections = 0;
                    centerPoint = new Vector3();
                    foreach (CellEdge ce in edgeList)
                    {
                        if (ce.hasIntersection)
                        {
                            CellEdge c = getOrAdd(ce, edgeDictionaryOrphans);
                            numEdgesWithIntersections++;
                            centerPoint += ce.intersectionPoint;
                        }
                    }

                    //salta le celle tutte piene e quelle tutte vuote
                    if (numEdgesWithIntersections == 0 || numEdgesWithIntersections == 8)
                    {
                        continue;
                    }

                    // ora che sappiamo quanti spigoli hanno intersezioni calcola il punto medio tra loro e settalo come punto centrale della cella
                    // dual contour - per infighettarlo qua dovresti applicare la QEF, invece del punto medio tra gli spigoli che hanno intersezioni
                    centerPoint = centerPoint / numEdgesWithIntersections;


                    int k = 0;
                    foreach (CellEdge ce in edgeList)
                    {
                        if (ce.hasIntersection)
                        {
                            CellEdge c = getOrAdd(ce, edgeDictionaryOrphans);

                            //if (numEdgesWithIntersections == 4) {
                            // c = getOrAdd(ce, edgeDictionary);
                            //if (c.cells[k] != Vector3.zero) Debug.Log("ERROR"); //TODO: check why I would possibly overwrite a preesisting(?) [k] value
                            c.cells[k] = centerPoint; //questa cosa della k, vista dopo anni, sembra funzionare per caso...
                        }
                        k++;
                        if (k > 3)
                        {
                            k = 0;
                        }
                    }

                    //Debug.Log("edgeDictionaryOrphans:" + edgeDictionaryOrphans.Count());
                }
            }
        } // fine del mega ciclo



        List <String> edgesKeysToMove = new List <String>();//edgeDictionaryOrphans.Keys.Except(keysToInclude).ToList();

        foreach (CellEdge ce in edgeDictionaryOrphans.Values)
        {
            if (ce.cells.Count(v => v != Vector3.zero) == 4)
            {
                edgesKeysToMove.Add(ce.name);
            }
        }

        foreach (String key in edgesKeysToMove)
        {
            CellEdge ce = edgeDictionaryOrphans[key];
            getOrAdd(ce, edgeDictionary);
            edgeDictionaryOrphans.Remove(ce.name);
        }

        mapData.edgeDictionary        = edgeDictionary;
        mapData.edgeDictionaryOrphans = edgeDictionaryOrphans;



        return(mapData);
    }