예제 #1
0
 public static  OcclusionCell <T>[,] OcGrid(Vector2 size)
 {
     OcclusionCell <T>[,] grid = new OcclusionCell <T> [(int)size.x, (int)size.y];
     for (int i = 0; i < size.x; i++)
     {
         for (int j = 0; j < size.y; j++)
         {
             grid[i, j].nullCell = true;
         }
     }
     return(grid);
 }
예제 #2
0
    // new Intersection
    /// <summary>
    /// Calculates resultant PointValues when 2D Raster (img) is projected along Frustum at Mesh (vertices).
    /// Mesh represented by list of vertices.
    /// NOTE: projection's FOV should be full FOV angles, not half-angles.
    /// </summary>
    public List <PointValue <byte> > Intersection(Frustum projection, ref List <Vector3> vertices, ref byte[,] raster)
    {
        /// setup
        List <PointValue <byte> > Results = new List <PointValue <byte> >();

        VerticesInView = 0;
        Vector2 ImgSize = new Vector2();

        ImgSize.x = raster.GetLength(0);
        ImgSize.y = raster.GetLength(1);

        Vector2 OcGridSize = GridSize(projection.FOV);

        OcclusionCell <byte>[,] ocGrid = OcclusionCell <byte> .OcGrid(OcGridSize);

        /// try each vertex
        for (i = 0; i < vertices.Count; i++)
        {
            /// calculate position vector (world space)
            Vector3 Pworld = Vector(projection.Transform.position, vertices[i]);

            /// convert position vector (world space) to position vector (Frustum space)
            Vector3 Plocal = projection.Transform.InverseTransformVector(Pworld);

            /// convert position vector (Frustum space) to view vector (Frustum space)
            ViewVector Vlocal = new ViewVector(Plocal);

            /// check if view vector is within Frustum FOV
            if (Math.Abs(Vlocal.Theta) < projection.FOV.Theta / 2.0 &&
                Math.Abs(Vlocal.Phi) < projection.FOV.Phi / 2.0)
            {
                VerticesInView++;

                /// map view vector to occlusion grid
                iOc = (int)(OcGridSize.x / 2 + OcGridSize.x * (Vlocal.Theta / projection.FOV.Theta));
                jOc = (int)(OcGridSize.y / 2 + OcGridSize.y * (Vlocal.Phi / projection.FOV.Phi));

                if (ocGrid[iOc, jOc].nullCell || Pworld.magnitude < ocGrid[iOc, jOc].distance)
                {
                    /// map view vector to Img grid
                    iImg = (int)(ImgSize.x / 2 + ImgSize.x * (Vlocal.Theta / projection.FOV.Theta));
                    jImg = (int)(ImgSize.y / 2 + ImgSize.y * (Vlocal.Phi / projection.FOV.Phi));

                    ocGrid[iOc, jOc].closest  = vertices[i];
                    ocGrid[iOc, jOc].distance = Pworld.magnitude;
                    ocGrid[iOc, jOc].value    = raster[iImg, jImg];
                    ocGrid[iOc, jOc].nullCell = false;
                }
            }
        }

        // add vertices in occluded grid
        for (i = 0; i < OcGridSize.x; i++)
        {
            for (j = 0; j < OcGridSize.y; j++)
            {
                if (!ocGrid[i, j].nullCell)
                {
                    Results.Add(new PointValue <byte>(ocGrid[i, j].closest, ocGrid[i, j].value));
                }
            }
        }

        CheckedVertices     = vertices.Count;
        NonOccludedVertices = Results.Count;
        return(Results);
    }
예제 #3
0
    /* OLD INTERSECTION VERSION
     * /// <summary>
     * /// Calculates resultant PointValues when 2D Raster (img) is projected along Frustum at Mesh (vertices).
     * /// Mesh represented by list of vertices.
     * /// NOTE 1: does not currently account for occlusion.
     * /// NOTE 2: projection's FOV should be full FOV angles, not half-angles.
     * /// NOTE 3: Attempted to make generic. See note at begining of file.
     * /// </summary>
     * public List<PointValue<byte>> Intersection(Frustum projection, byte[,] img, List<Vector3> vertices)
     * {
     *  /// setup
     *  ImgPCi = img.GetLength(0);
     *  ImgPCj = img.GetLength(1);
     *  VerticesInView = 0;
     *
     *  /// update occlusion grid
     *  /// Cannot predeclare OcPixels because cannot add Dictionary components in declaration.
     *  Dictionary<string, int> OcPixels = RequiredGrid(projection.FOV);
     *  // Predeclaration of ocGrid has no benefit due to array type an dynamic size.
     *  OcclusionCell<byte>[,] ocGrid = new OcclusionCell<byte>[OcPixels["i"], OcPixels["j"]];
     *  for (i = 0; i < OcPixels["i"]; i++)
     *  {
     *      for (j = 0; j < OcPixels["j"]; j++)
     *      {
     *          ocGrid[i, j].nullCell = true;
     *      }
     *  }
     *
     *  /// try each vertex
     *  for (i = 0; i < vertices.Count; i++)
     *  {
     *      /// calculate position vector (world space)
     *      Vector(projection.Transform.position, vertices[i], ref Pworld);
     *
     *      /// convert position vector (world space) to position vector (Frustum space)
     *      Plocal = projection.Transform.InverseTransformVector(Pworld);
     *
     *      /// convert position vector (Frustum space) to view vector (Frustum space)
     *      Vlocal.Update(Plocal);
     *
     *      /// check if view vector is within Frustum FOV
     *      if (Math.Abs(Vlocal.Theta) < projection.FOV.Theta / 2.0 &&
     *          Math.Abs(Vlocal.Phi) < projection.FOV.Phi / 2.0)
     *      {
     *          VerticesInView++;
     *
     *          /// map view vector to occlusion grid
     *          iOc = (int)(OcPixels["i"] / 2 + OcPixels["i"] * (Vlocal.Theta / projection.FOV.Theta));
     *          jOc = (int)(OcPixels["j"] / 2 + OcPixels["j"] * (Vlocal.Phi / projection.FOV.Phi));
     *
     *          /// add to occlusion grid as new PointValue if not occluded
     *
     *          if (ocGrid[iOc, jOc].nullCell || Pworld.magnitude < ocGrid[iOc, jOc].distance)
     *          {
     *              /// map view vector to img pixel grid
     *              iImg = (int)(ImgPCi / 2 + ImgPCi * (Vlocal.Theta / projection.FOV.Theta));
     *              jImg = (int)(ImgPCj / 2 + ImgPCj * (Vlocal.Phi / projection.FOV.Phi));
     *
     *              /// update occlusion grid
     *              ocGrid[iOc, jOc].pv.Update(vertices[i], img[iImg, jImg]);
     *              ocGrid[iOc, jOc].distance = Pworld.magnitude;
     *              ocGrid[iOc, jOc].nullCell = false;
     *          }
     *      }
     *  }
     *
     *  /// Alteratively could prevent reallocating using Result.Clear(), however is slow
     *  Result = new List<PointValue<byte>>();
     *  for (i = 0; i < ocGrid.GetLength(0); i++)
     *  {
     *      for (j = 0; j < ocGrid.GetLength(1); j++)
     *      {
     *          if (!ocGrid[i, j].nullCell)
     *              Result.Add(ocGrid[i, j].pv);
     *      }
     *  }
     *  NonOccludedVertices = Result.Count;
     *  return Result;
     * }
     */

    // new Intersection
    /// <summary>
    /// Calculates resultant PointValues when 2D Raster (img) is projected along Frustum at Mesh (vertices).
    /// Mesh represented by list of vertices.
    /// NOTE 1: does not currently account for occlusion.
    /// NOTE 2: projection's FOV should be full FOV angles, not half-angles.
    /// NOTE 3: Attempted to make generic. See note at begining of file.
    /// </summary>
    public void Intersection(Frustum projection, List <Vector3> vertices,
                             out List <Vector3> InView, out List <Vector3> OutView, out List <Vector3> Occluded,
                             out List <ViewVector> VV, out List <Vector3> PVecs)
    {
        /// setup
        InView   = new List <Vector3>();
        OutView  = new List <Vector3>();
        Occluded = new List <Vector3>();
        VV       = new List <ViewVector>();
        PVecs    = new List <Vector3>();

        // Predeclaration of ocGrid has no benefit due to array type an dynamic size.
        OcclusionCell <byte>[,] ocGrid = new OcclusionCell <byte> [(int)OccGridSize.x,
                                                                   (int)OccGridSize.y];
        for (i = 0; i < OccGridSize.x; i++)
        {
            for (j = 0; j < OccGridSize.y; j++)
            {
                ocGrid[i, j].nullCell = true;
                ocGrid[i, j].occluded = new List <Vector3>();
            }
        }

        /// try each vertex
        for (i = 0; i < vertices.Count; i++)
        {
            /// calculate position vector (world space)
            Pworld = Vector(projection.Transform.position, vertices[i]);

            /// convert position vector (world space) to position vector (Frustum space)
            Plocal = projection.Transform.InverseTransformVector(Pworld);
            PVecs.Add(Plocal);

            /// convert position vector (Frustum space) to view vector (Frustum space)
            ViewVector Vlocal = new ViewVector(Plocal);
            VV.Add(Vlocal);

            /// check if view vector is within Frustum FOV
            if (Math.Abs(Vlocal.Theta) < projection.FOV.Theta / 2.0 &&
                Math.Abs(Vlocal.Phi) < projection.FOV.Phi / 2.0)
            {
                /// map view vector to occlusion grid
                iOc = (int)(OccGridSize.x / 2 + OccGridSize.x * (Vlocal.Theta / projection.FOV.Theta));
                jOc = (int)(OccGridSize.y / 2 + OccGridSize.y * (Vlocal.Phi / projection.FOV.Phi));

                if (ocGrid[iOc, jOc].nullCell)
                {
                    ocGrid[iOc, jOc].closest  = vertices[i];
                    ocGrid[iOc, jOc].distance = Pworld.magnitude;
                    ocGrid[iOc, jOc].nullCell = false;
                }
                else if (Pworld.magnitude < ocGrid[iOc, jOc].distance)
                {
                    ocGrid[iOc, jOc].occluded.Add(ocGrid[iOc, jOc].closest);
                    ocGrid[iOc, jOc].closest  = vertices[i];
                    ocGrid[iOc, jOc].distance = Pworld.magnitude;
                }
                else
                {
                    ocGrid[iOc, jOc].occluded.Add(vertices[i]);
                }
            }
            else
            {
                OutView.Add(vertices[i]);
            }
        }

        // add vertices in occluded grid
        for (i = 0; i < OccGridSize.x; i++)
        {
            for (j = 0; j < OccGridSize.y; j++)
            {
                InView.Add(ocGrid[i, j].closest);
                Occluded.AddRange(ocGrid[i, j].occluded);
            }
        }

        InViewCount   = InView.Count;
        OutViewCount  = OutView.Count;
        OccludedCount = Occluded.Count;
    }
예제 #4
0
    /// <summary>
    /// Calculates resultant PointValues when 2D Raster (img) is projected along Frustum at Mesh (vertices).
    /// Mesh represented by list of vertices.
    /// NOTE 1: does not currently account for occlusion.
    /// NOTE 2: projection's FOV should be full FOV angles, not half-angles.
    /// </summary>
    public List <PointValue <T> > Intersection <T>(Frustum projection, T[,] img, List <Vector3> vertices)
    {
        /// setup
        int imgPCi = img.GetLength(0);
        int imgPCj = img.GetLength(1);
        List <PointValue <T> > result = new List <PointValue <T> >();

        VerticesInView = 0;

        /// create occlusion grid
        Dictionary <string, int> ocPixels = RequiredGrid(projection.FOV);
        int ocPCi = ocPixels["i"];
        int ocPCj = ocPixels["j"];

        OcclusionCell <T>[,] ocGrid = new OcclusionCell <T> [ocPCi, ocPCj];
        for (int i = 0; i < ocGrid.GetLength(0); i++)
        {
            for (int j = 0; j < ocGrid.GetLength(1); j++)
            {
                ocGrid[i, j].nullCell = true;
            }
        }

        /// try each vertex
        foreach (Vector3 vertex in vertices)
        {
            /// calculate position vector (world space)
            Vector3 Pworld = Vector(projection.Transform.position, vertex);

            /// convert position vector (world space) to position vector (Frustum space)
            Vector3 Plocal = projection.Transform.InverseTransformVector(Pworld);

            /// convert position vector (Frustum space) to view vector (Frustum space)
            ViewVector Vlocal = new ViewVector(Plocal);

            /// check if view vector is within Frustum FOV
            if (Math.Abs(Vlocal.Theta) < projection.FOV.Theta / 2.0 &&
                Math.Abs(Vlocal.Phi) < projection.FOV.Phi / 2.0)
            {
                VerticesInView++;

                /// map view vector to occlusion grid
                int ioc = (int)(ocPCi / 2 + ocPCi * (Vlocal.Theta / projection.FOV.Theta));
                int joc = (int)(ocPCj / 2 + ocPCj * (Vlocal.Phi / projection.FOV.Phi));

                /// add to occlusion grid as new PointValue if not occluded
                if (ocGrid[ioc, joc].nullCell || Pworld.magnitude < ocGrid[ioc, joc].distance)
                {
                    /// map view vector to img pixel grid
                    int iImg = (int)(imgPCi / 2 + imgPCi * (Vlocal.Theta / projection.FOV.Theta));
                    int jImg = (int)(imgPCj / 2 + imgPCj * (Vlocal.Phi / projection.FOV.Phi));

                    /// update occlusion grid
                    ocGrid[ioc, joc].pv       = new PointValue <T>(vertex, img[iImg, jImg]);
                    ocGrid[ioc, joc].distance = Pworld.magnitude;
                    ocGrid[ioc, joc].nullCell = false;
                }
            }
        }

        for (int i = 0; i < ocGrid.GetLength(0); i++)
        {
            for (int j = 0; j < ocGrid.GetLength(1); j++)
            {
                if (!ocGrid[i, j].nullCell)
                {
                    result.Add(ocGrid[i, j].pv);
                }
            }
        }
        nonOccludedVertices = result.Count;
        return(result);
    }
예제 #5
0
    /// <summary>
    /// Calculates resultant PointValues when 2D Raster (img) is projected along Frustum at Mesh (vertices).
    /// Mesh represented by list of vertices.
    /// NOTE 1: does not currently account for occlusion.
    /// NOTE 2: projection's FOV should be full FOV angles, not half-angles.
    /// NOTE 3: Attempted to make generic. See note at begining of file.
    /// </summary>
    public List <PointValue <byte> > Intersection(Frustum projection, byte[,] img, List <Vector3> vertices)
    {
        /// setup
        ImgPCi         = img.GetLength(0);
        ImgPCj         = img.GetLength(1);
        VerticesInView = 0;

        /// update occlusion grid
        /// Cannot predeclare OcPixels because cannot add Dictionary components in declaration.
        Dictionary <string, int> OcPixels = RequiredGrid(projection.FOV);

        // Predeclaration of ocGrid has no benefit due to array type an dynamic size.
        OcclusionCell <byte>[,] ocGrid = new OcclusionCell <byte> [OcPixels["i"], OcPixels["j"]];
        for (i = 0; i < OcPixels["i"]; i++)
        {
            for (j = 0; j < OcPixels["j"]; j++)
            {
                ocGrid[i, j].nullCell = true;
            }
        }

        /// try each vertex
        for (i = 0; i < vertices.Count; i++)
        {
            /// calculate position vector (world space)
            Vector(projection.Transform.position, vertices[i], ref Pworld);

            /// convert position vector (world space) to position vector (Frustum space)
            Plocal = projection.Transform.InverseTransformVector(Pworld);

            /// convert position vector (Frustum space) to view vector (Frustum space)
            Vlocal.Update(Plocal);

            /// check if view vector is within Frustum FOV
            if (Math.Abs(Vlocal.Theta) < projection.FOV.Theta / 2.0 &&
                Math.Abs(Vlocal.Phi) < projection.FOV.Phi / 2.0)
            {
                VerticesInView++;

                /// map view vector to occlusion grid
                iOc = (int)(OcPixels["i"] / 2 + OcPixels["i"] * (Vlocal.Theta / projection.FOV.Theta));
                jOc = (int)(OcPixels["j"] / 2 + OcPixels["j"] * (Vlocal.Phi / projection.FOV.Phi));

                /// add to occlusion grid as new PointValue if not occluded

                if (ocGrid[iOc, jOc].nullCell || Pworld.magnitude < ocGrid[iOc, jOc].distance)
                {
                    /// map view vector to img pixel grid
                    iImg = (int)(ImgPCi / 2 + ImgPCi * (Vlocal.Theta / projection.FOV.Theta));
                    jImg = (int)(ImgPCj / 2 + ImgPCj * (Vlocal.Phi / projection.FOV.Phi));

                    /// update occlusion grid
                    ocGrid[iOc, jOc].pv.Update(vertices[i], img[iImg, jImg]);
                    ocGrid[iOc, jOc].distance = Pworld.magnitude;
                    ocGrid[iOc, jOc].nullCell = false;
                }
            }
        }

        /// Alteratively could prevent reallocating using Result.Clear(), however is slow
        Result = new List <PointValue <byte> >();
        for (i = 0; i < ocGrid.GetLength(0); i++)
        {
            for (j = 0; j < ocGrid.GetLength(1); j++)
            {
                if (!ocGrid[i, j].nullCell)
                {
                    Result.Add(ocGrid[i, j].pv);
                }
            }
        }
        NonOccludedVertices = Result.Count;
        return(Result);
    }