public void CreateGraphWithObstacles() { // Create a list to store all faces of the graph in the grid List <Face> faces = new List <Face>(); //Iterate through all the faces in the grid foreach (var face in _voxelGrid.GetFaces()) { //65 Get the voxels associated with this face GraphVoxel voxelA = (GraphVoxel)face.Voxels[0]; GraphVoxel voxelB = (GraphVoxel)face.Voxels[1]; // Check if both voxels exist, are not obstacle and are active if (voxelA != null && !voxelA.IsVoid && voxelA.IsActive && !voxelA.IsObstacle && voxelB != null && !voxelB.IsVoid && voxelB.IsActive && !voxelB.IsObstacle) { // Add face to list faces.Add(face); } } // Create the edges from the graph using the faces (the voxels are the vertices) var graphEdges = faces.Select(f => new TaggedEdge <GraphVoxel, Face>((GraphVoxel)f.Voxels[0], (GraphVoxel)f.Voxels[1], f)); // Create the undirected graph from the edges _graph = graphEdges.ToUndirectedGraph <GraphVoxel, TaggedEdge <GraphVoxel, Face> >(); }
public VoxelGrid(int height, Vector3 origin, float voxelSize) { //07 Read grid dimensions in X and Z from image GridSize = new Vector3Int(10, 10, 10); Origin = origin; VoxelSize = voxelSize; Voxels = new Voxel[GridSize.x, GridSize.y, GridSize.z]; for (int x = 0; x < GridSize.x; x++) { for (int y = 0; y < GridSize.y; y++) { for (int z = 0; z < GridSize.z; z++) { Voxels[x, y, z] = new GraphVoxel(new Vector3Int(x, y, z), this, 1f, 0.96f); } } } //08 Add make Faces, Corners and Edges MakeFaces(); MakeCorners(); MakeEdges(); }
/// <summary> /// Return all blocks that are not allready place in the grid /// </summary> #region Constructors /// <summary> /// Constructor for a basic <see cref="VoxelGrid"/> /// </summary> /// <param name="size">Size of the grid</param> /// <param name="origin">Origin of the grid</param> /// <param name="voxelSize">The size of each <see cref="Voxel"/></param> public VoxelGrid(Vector3Int size, Vector3 origin, float voxelSize) { GridSize = size; Origin = origin; VoxelSize = voxelSize; Voxels = new Voxel[GridSize.x, GridSize.y, GridSize.z]; for (int x = 0; x < GridSize.x; x++) { for (int y = 0; y < GridSize.y; y++) { for (int z = 0; z < GridSize.z; z++) { GraphVoxel newVoxel = new GraphVoxel(new Vector3Int(x, y, z), this, 1f, 0.96f); Voxels[x, y, z] = newVoxel; newVoxel.SetState(1f); //Voxels[x, y, z] = new GraphVoxel(new Vector3Int(x, y, z), this, 1f, 0.96f); } } } MakeFaces(); MakeCorners(); MakeEdges(); }
private void SetClickedAsTarget() { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); //check if mouse hit if (Physics.Raycast(ray, out RaycastHit hit)) { //transform ths hitting object to gameoject Transform objectHit = hit.transform; //if the hit voxel is backyard voxel //II or condition to change state between is target or not || objectHit.gameObject.layer == LayerMask.NameToLayer("Plot") if (objectHit.gameObject.layer == LayerMask.NameToLayer("Backyard")) { //get its name(index) GraphVoxel selected = null; string voxelName = objectHit.name; var index = voxelName.Split('_').Select(v => int.Parse(v)).ToArray(); //reture its index selected = (GraphVoxel)_voxelGrid.Voxels[index[0], index[1], index[2]]; //string[] voxelName = objectHit.name.Split('_'); //int x = int.Parse(voxelName[1]); //int y = int.Parse(voxelName[2]); //int z = int.Parse(voxelName[3]); //Vector3Int ind = new Vector3Int(x, y, z); //GraphVoxel voxel = (GraphVoxel)_voxelGrid.Voxels[ind.x, ind.y, ind.z]; selected.SetAsTarget(); //add selected target voxel to the list if (selected.IsTarget) { _targets.Add(selected); } else { _targets.Remove(selected); } } } }
// Create the method to set clicked voxel as target /// <summary> /// Cast a ray where the mouse pointer is, turning the selected voxel into a target /// </summary> private void SetClickedAsTarget() { // Cast ray from camer Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // If ray hits something, continue if (Physics.Raycast(ray, out RaycastHit hit)) { Transform objectHit = hit.transform; // FIRST Compare tag of clicked object with VoidVoxel tag // SECOND Compare tag to TargetVoxel with || if (objectHit.CompareTag("Voxel") || objectHit.CompareTag("TargetVoxel")) { // Read the name of the obeject and split it by _ string[] name = objectHit.name.Split('_'); // Construct index from split name int x = int.Parse(name[1]); int y = int.Parse(name[2]); int z = int.Parse(name[3]); Vector3Int index = new Vector3Int(x, y, z); // Retrieve voxel by index GraphVoxel voxel = (GraphVoxel)_voxelGrid.Voxels[index.x, index.y, index.z]; // Set voxel as target and test voxel.SetAsTarget(); // If voxel has be set as target, add it to _targets list if (voxel.IsTarget) { _targets.Add(voxel); } // Else, remove it from _targets list else { _targets.Remove(voxel); } } } }
/// <summary> /// Create voxel grid from the size of input image /// </summary> /// <param name="input"></input image> /// <param name="origin"></origin> /// <param name="voxelSize"></size> /// <param name="height"></param> /// <param name="parent"></param> /// public VoxelGrid(Texture2D input, Vector3 origin, int height, float voxelSize, Transform parent = null) { // create new grid with image size GridSize = new Vector3Int(input.width, height, input.height); Origin = origin; VoxelSize = voxelSize; Voxels = new Voxel[GridSize.x, GridSize.y, GridSize.z]; for (int x = 0; x < GridSize.x; x++) { for (int y = 0; y < GridSize.y; y++) { for (int z = 0; z < GridSize.z; z++) { if (y == 0) { Voxels[x, y, z] = new GraphVoxel( new Vector3Int(x, y, z), this, 1f, createCollider: true, parent: parent); } else { Voxels[x, y, z] = new GraphVoxel( new Vector3Int(x, y, z), this, 1f); } } } } MakeFaces(); MakeCorners(); MakeEdges(); }
/// <summary> /// Reads an image pixel data and set the color pixels and corresponding label/quality to the grid /// </summary> /// <param name="image">The reference image</param> /// <param name="layer">The target layer</param> public void SetStatesFromImage(Texture2D inputImage, int layer = 0) { // Iterate through the XZ plane for (int x = 0; x < GridSize.x; x++) { for (int z = 0; z < GridSize.z; z++) { // Get the pixel color from the image Color pixel = inputImage.GetPixel(x, z); //read voxel as its child:graphvoxel GraphVoxel voxel = (GraphVoxel)Voxels[x, 0, z]; //read RGB channel float[] colorScores = new float[8] { Mathf.Abs(pixel.r - 0) + Mathf.Abs(pixel.g - 1) + Mathf.Abs(pixel.b - 1), //Cyan Mathf.Abs(pixel.r - 0) + Mathf.Abs(pixel.g - 0) + Mathf.Abs(pixel.b - 1), //Blue Mathf.Abs(pixel.r - 1) + Mathf.Abs(pixel.g - 0) + Mathf.Abs(pixel.b - 1), //Magenta Mathf.Abs(pixel.r - 1) + Mathf.Abs(pixel.g - 0) + Mathf.Abs(pixel.b - 0), //Red Mathf.Abs(pixel.r - 0) + Mathf.Abs(pixel.g - 1) + Mathf.Abs(pixel.b - 0), //Green Mathf.Abs(pixel.r - 1) + Mathf.Abs(pixel.g - 1) + Mathf.Abs(pixel.b - 0), //Yellow Mathf.Abs(pixel.r - 1) + Mathf.Abs(pixel.g - 1) + Mathf.Abs(pixel.b - 1), //White Mathf.Abs(pixel.r - .5f) + Mathf.Abs(pixel.g - .5f) + Mathf.Abs(pixel.b - .5f) //Gray }; //Get the colors right float biggestScore = 0; int colorIndex = 0; int colorQuality = 0; for (int i = 0; i < colorScores.Length; i++) { if (colorScores[i] > biggestScore) { biggestScore = colorScores[i]; colorIndex = i; colorQuality = i; } } Voxels[x, layer, z].FColor = (FunctionColor)colorIndex; Voxels[x, layer, z].Qname = (ColorQuality)colorQuality; // assign the layermask to be used in analysis foreach (var voxels in Voxels) { if (voxel.IsActive && voxel.VoxelCollider.gameObject.layer == 0) { if (voxel.FColor == FunctionColor.Blue) { voxel.VoxelCollider.gameObject.layer = LayerMask.NameToLayer("Backyard"); } else if (voxel.FColor == FunctionColor.Red) { voxel.VoxelCollider.gameObject.layer = LayerMask.NameToLayer("House"); } else if (voxel.FColor == FunctionColor.Yellow) { voxel.VoxelCollider.gameObject.layer = LayerMask.NameToLayer("Street"); } else if (voxel.FColor == FunctionColor.Magenta) { voxel.VoxelCollider.gameObject.layer = LayerMask.NameToLayer("Frontyard"); } else if (voxel.FColor == FunctionColor.Green) { voxel.VoxelCollider.gameObject.layer = LayerMask.NameToLayer("Tree"); } else if (voxel.FColor == FunctionColor.White) { voxel.VoxelCollider.gameObject.layer = LayerMask.NameToLayer("Plot"); } else if (voxel.FColor == FunctionColor.Cyan) { voxel.VoxelCollider.gameObject.layer = LayerMask.NameToLayer("LandTexture"); } else if (voxel.FColor == FunctionColor.Gray) { voxel.VoxelCollider.gameObject.layer = LayerMask.NameToLayer("SmallBuilding"); } else if (voxel.FColor == FunctionColor.Empty) { voxel.VoxelCollider.gameObject.layer = LayerMask.NameToLayer("EmptyLand"); } } } } } }
/// <summary> /// Reads an image pixel data and set the color pixels and corresponding label/quality to the grid /// </summary> /// <param name="image">The reference image</param> /// <param name="layer">The target layer</param> public void SetStatesFromImage(Texture2D inputImage, int layer = 0) { // Iterate through the XZ plane for (int x = 0; x < GridSize.x; x++) { for (int z = 0; z < GridSize.z; z++) { // Get the pixel color from the image Color pixel = inputImage.GetPixel(x, z); //read voxel as its child:graphvoxel GraphVoxel voxel = (GraphVoxel)Voxels[x, 0, z]; //read RGB channel float[] colorScores = new float[9] { Mathf.Abs(pixel.r - 0) + Mathf.Abs(pixel.g - 1) + Mathf.Abs(pixel.b - 1), //Black Mathf.Abs(pixel.r - 1) + Mathf.Abs(pixel.g - 0) + Mathf.Abs(pixel.b - 0), //Red Mathf.Abs(pixel.r - 1) + Mathf.Abs(pixel.g - 1) + Mathf.Abs(pixel.b - 0), //Yellow Mathf.Abs(pixel.r - 0) + Mathf.Abs(pixel.g - 1) + Mathf.Abs(pixel.b - 0), //Green Mathf.Abs(pixel.r - 0) + Mathf.Abs(pixel.g - 1) + Mathf.Abs(pixel.b - 1), //Cyan Mathf.Abs(pixel.r - 1) + Mathf.Abs(pixel.g - 0) + Mathf.Abs(pixel.b - 1), //Magenta Mathf.Abs(pixel.r - 0) + Mathf.Abs(pixel.g - 0) + Mathf.Abs(pixel.b - 1), //Blue Mathf.Abs(pixel.r - 1) + Mathf.Abs(pixel.g - 1) + Mathf.Abs(pixel.b - 1), //White Mathf.Abs(pixel.r - .5f) + Mathf.Abs(pixel.g - .5f) + Mathf.Abs(pixel.b - .5f) //Gray }; //Get the colors right float biggestScore = 0; int colorIndex = 0; for (int i = 0; i < colorScores.Length; i++) { if (colorScores[i] > biggestScore) { biggestScore = colorScores[i]; colorIndex = i; } } Voxels[x, layer, z].FColor = (FunctionColor)colorIndex; /* * //0,0,1 * if (pixel.b > pixel.r && pixel.b > pixel.g) * { * Voxels[x, layer, z].FColor = FunctionColor.Blue; * Voxels[x, layer, z].Qname = ColorQuality.Backyard; * * } * * * * //0,1,1 * else if (pixel.b > pixel.r && pixel.g > pixel.r) * { * Voxels[x, layer, z].FColor = FunctionColor.Cyan; * Voxels[x, layer, z].Qname = ColorQuality.LandTexture; * } * * else if (pixel.r == 0.5f && pixel.g == 0.5f) * { * Voxels[x, layer, z].FColor = FunctionColor.Gray; * } * * //0,1,0 * else if (pixel.g > pixel.r && pixel.g > pixel.b) * { * Voxels[x, layer, z].FColor = FunctionColor.Green; * //Voxels[x, layer, z]._voxelGO.GetComponent<MeshRenderer>().material = Resources.Load<Material>("Materials/Tree"); * Voxels[x, layer, z].Qname = ColorQuality.Tree; * } * //1,0,1 * else if (pixel.r > pixel.g && pixel.b > pixel.g && pixel.r <= pixel.b) * { * Voxels[x, layer, z].FColor = FunctionColor.Magenta; * //Voxels[x, layer, z]._voxelGO.GetComponent<MeshRenderer>().material = Resources.Load<Material>("Materials/FrontYard"); * Voxels[x, layer, z].Qname = ColorQuality.Frontyard; * } * //1,1,0 pixel.g / pixel.r>= 1f * else if (pixel.r > pixel.b && pixel.g > pixel.b) * { * Voxels[x, layer, z].FColor = FunctionColor.Yellow; * //Voxels[x, layer, z]._voxelGO.GetComponent<MeshRenderer>().material = Resources.Load<Material>("Materials/Street"); * Voxels[x, layer, z].Qname = ColorQuality.Street; * } * //1,0,0 * else if (pixel.r > pixel.g && pixel.r > pixel.b) * { * Voxels[x, layer, z].FColor = FunctionColor.Red; * //Voxels[x, layer, z]._voxelGO.GetComponent<MeshRenderer>().material = Resources.Load<Material>("Materials/House"); * Voxels[x, layer, z].Qname = ColorQuality.House; * } * * //1,1,1 * else if (pixel.r == 1f && pixel.g == 1f && pixel.b == 1f) * { * Voxels[x, layer, z].FColor = FunctionColor.White; * //Voxels[x, layer, z]._voxelGO.GetComponent<MeshRenderer>().material = Resources.Load<Material>("Materials/Plot"); * Voxels[x, layer, z].Qname = ColorQuality.Plot; * } * * * // Check if pixel is red * //if (pixel.r >pixel.g) * //{ * // // Set respective color to voxel * // Voxels[x, layer, z].FColor = FunctionColor.Red; * //}*/ } } }