Esempio n. 1
0
 //Creates VoxelGrids and saves them in the HashMap.
 //Always creates a grid with size (block_generator_radius*2+1)^3
 public void GenerateDenseVoxelGrids(Vector3Int gridcoords)
 {
     for (int z = gridcoords.z - generation_radius; z <= gridcoords.z + generation_radius; z++)
     {
         for (int y = gridcoords.y - generation_radius; y <= gridcoords.y + generation_radius; y++)
         {
             for (int x = gridcoords.x - generation_radius; x <= gridcoords.x + generation_radius; x++)
             {
                 Vector3Int position = new Vector3Int(x, y, z);
                 if (!voxelblock_hash_table.ContainsKey(ToKey(position)))
                 {
                     GameObject g = Instantiate(dense_voxel_grid);
                     g.transform.parent        = this.transform;
                     g.transform.localScale    = new Vector3(1, 1, 1);
                     g.transform.localRotation = Quaternion.identity;
                     g.transform.localPosition = new Vector3(x, y, z);
                     g.name = "Dense_" + x + "_" + y + "_" + z;
                     DenseVoxelGrid dvg = g.GetComponent <DenseVoxelGrid>();
                     dvg.Render();
                     voxelblock_hash_table.Add(ToKey(position), g);
                 }
             }
         }
     }
 }
Esempio n. 2
0
    //Function to update each voxel within a voxel grid
    public void UpdateDenseVoxelGrid(DenseVoxelGrid dvg, int current_update_frame)
    {
        //Only update if voxelgrid was not updated this frame
        if (current_update_frame == dvg.last_update_frame)
        {
            return;
        }

        //Do for every voxel in the Grid:
        for (int z = 0; z < dvg.grid_size.z; z++)
        {
            for (int y = 0; y < dvg.grid_size.y; y++)
            {
                for (int x = 0; x < dvg.grid_size.x; x++)
                {
                    //Convert voxelgrid coordinates to world coordinates
                    Vector3 worldcoord = dvg.DenseGridCoordToWorldCoord(x, y, z);
                    //Retrieve corresponding pixel coordinates
                    Vector2Int pixelcoord = GetPixelFromCoords(worldcoord);
                    //Check if pixel is within camera image
                    if (pixelcoord.x >= 0 && pixelcoord.y >= 0 && pixelcoord.x < interface_.differenceImage.width && pixelcoord.y < interface_.differenceImage.height)
                    {
                        //Retrieve VoxelType from pixelcoords
                        VoxelType vt = GetVoxelType(pixelcoord);
                        //Only update value if it is green/red in the image
                        if (vt != VoxelType.EMPTY)
                        {
                            //Calculate the exact distance btw the camera and the voxel
                            float dist_exact = GetDistanceToCameraScreen(worldcoord);
                            //Calculate the measured distance btw the camera and the voxel
                            float dist_measured = GetMeasuredDistance(vt, pixelcoord);
                            bool  out_of_range  = false;
                            //Calculate the TSDF value of this voxel
                            float tsdf = GetTSDFValue(dist_exact, dist_measured, out out_of_range);
                            //If the voxel is out of range (last part of the tsdf), truncate, else update the voxel
                            if (!out_of_range)
                            {
                                dvg.active_count += UpdateVoxel(ref dvg.grid[x, y, z], tsdf, vt);
                            }
                        }
                    }
                }
            }
        }
        //Render the updated block
        dvg.Render();

        //Set current update frame in voxelgrid
        dvg.last_update_frame = current_update_frame;
    }
Esempio n. 3
0
    //Main Method to Update Voxel Value.
    //Input:
    //value - calculated from the TSD Function.
    //x, y, z - grid coordinates of Voxel to update
    //current_update_frame - this ensures that voxels only get updated once

    //Main Method Called From Reconstruction Button or via online update
    public void ReconstructScene()
    {
        Debug.Log("Reconstruction");
        //Used to measure reconstruction time
        var watch = System.Diagnostics.Stopwatch.StartNew();
        //Step 1: Choose Pixels at Random and Project Point to 3D View
        int width  = interface_.differenceImage.width;
        int height = interface_.differenceImage.height;
        int ind    = 0;

        for (int i = 0; i < number_of_samples; i++)
        {
            VoxelType vt = VoxelType.EMPTY;
            //1.1 Draw a Random Pixel from difference Image
            Vector2Int pixel    = new Vector2Int();
            int        overflow = 0;
            //1.2 Check if pixel is not empty and repeat if necessary
            while (vt == VoxelType.EMPTY && overflow < 1000)
            {
                pixel.x = (int)(Random.value * width);
                pixel.y = (int)(Random.value * height);
                vt      = GetVoxelType(pixel);
                overflow++;
            }
            //1.3 Calculate coordinates of voxel from pixel depth value
            Vector3 voxelcoords = GetCoordsFromPixel(vt, pixel);
            //1.4 Recieve DenseVoxelGrid at this position or create a new one if necessary
            DenseVoxelGrid dvg = SVG.GetDenseVoxelGrid(voxelcoords);
            //1.5 Update DenseVoxelGrid at this position by backprojecting all voxels
            UpdateDenseVoxelGrid(dvg, update_frame);
            ind++;
        }
        Debug.Log(ind + " Pixels found a surface");

        //Step 3: Look for empty voxel blocks and remove them
        SVG.RemoveEmptyVoxelGrids();

        update_frame++;

        //Display elapsed time
        watch.Stop();
        var elapsedMs = watch.ElapsedMilliseconds;

        Debug.Log("Reconstruction took " + elapsedMs + "Milliseconds");
    }
Esempio n. 4
0
    //Does not have to be called every time, can also run in background
    //Removes all voxel Grids that do not contain any active voxels
    public void RemoveEmptyVoxelGrids()
    {
        List <string> toRemove = new List <string>();

        foreach (DictionaryEntry de in voxelblock_hash_table)
        {
            GameObject     g   = de.Value as GameObject;
            DenseVoxelGrid dvg = g.GetComponent <DenseVoxelGrid>();
            if (dvg.active_count == 0)
            {
                toRemove.Add(de.Key as string);
                Destroy(g);
            }
        }
        foreach (string s in toRemove)
        {
            voxelblock_hash_table.Remove(s);
        }
    }