private void Move(Direction direction) { CellEdge edge = currentCell.GetEdge(direction); if (edge is DungeonPassage) { SetLocation(edge.otherCell); } }
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); } }
public void SetEdge(Direction dir, CellEdge edge) { edges[(int)dir] = edge; iInitialisedEdgeCount += 1; }
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); }
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); }
public void SetEdge(Direction direction, CellEdge edge) { edges [(int)direction] = edge; edgeCount++; }
// 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; }
public void SetEdge (CellDirection direction, CellEdge edge) { edges[(int)direction] = edge; }
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; } } }
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); } }
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); }