Пример #1
0
        /// <summary>
        /// Returns i,j pixel coordinates of this ViewVector within 1D rep of pixelGrid
        /// of height, width spanning across FOV
        /// </summary>
        public int Map <T>(T[] grid, int height, int width, ViewVector FOV, Vector2 FOVReduction)
        {
            int i = (int)(width / 2 + width * (Theta / (FOV.Theta / FOVReduction.x)));
            int j = (int)(height / 2 + height * (Phi / (FOV.Phi / FOVReduction.y)));

            // ensure in grid
            if (i < 0)
            {
                throw new ArgumentOutOfRangeException("i", "less than zero");
            }
            if (i > width)
            {
                throw new ArgumentOutOfRangeException("i", "greater than width");
            }
            if (j < 0)
            {
                throw new ArgumentOutOfRangeException("j", "less than zero");
            }
            if (j > height)
            {
                throw new ArgumentOutOfRangeException("j", "greater than height");
            }

            int index = j * width + i;

            if (index > grid.Length)
            {
                throw new ArgumentOutOfRangeException("index", "greater than grid length");
            }

            return(index);
        }
Пример #2
0
    /// <summary>
    /// Returns list of all points in viewField using oc for occlusion approximation.
    /// Will update occluded and notInView to lists of vertices in those categories.
    /// NOTE: clearing lists, resetting metadata must be done BEFORE calling method.
    /// </summary>
    public List <CachedVertex> AllInView(List <SurfacePoints> extras, List <bool> meshGuide, Frustum viewField, Occlusion oc)
    {
        for (int i = 0; i < extras.Count; i++)
        {
            // check visibility
            if (meshGuide[i])
            {
                for (int j = 0; j < extras[i].Wvertices.Count; j++)
                {
                    Vector3    pt   = extras[i].Wvertices[j];
                    Vector3    Pvec = Vector(viewField.Transform.position, pt);
                    ViewVector vv   = viewField.ViewVec(pt);

                    if (viewField.FOV.Contains(vv))
                    {
                        Vector2      coords = vv.Map <Occlusion.OcclusionCell>(oc.grid, viewField.FOV);
                        CachedVertex cv     = new CachedVertex(pt, i, j);

                        if (oc.grid[(int)coords.x, (int)coords.y].nullCell ||
                            Pvec.magnitude < oc.grid[(int)coords.x, (int)coords.y].distance)
                        {
                            oc.grid[(int)coords.x, (int)coords.y].closest  = cv;
                            oc.grid[(int)coords.x, (int)coords.y].distance = Pvec.magnitude;
                            oc.grid[(int)coords.x, (int)coords.y].nullCell = false;
                            NonOccludedVertices++;
                        }
                        VerticesInView++;
                    }
                    CheckedVertices++;
                }
            }
        }
        return(oc.Points());
    }
Пример #3
0
    /// <summary>
    /// Projects raster values onto passed list of points from frustum viewField.
    /// Also updates mesh colors of meshes and points defined by meshList, meshIndices, pointIndices
    /// according to color1 to color2, value1 to value2 scale.
    /// </summary>
    private List <PointValue <byte> > Project(List <CachedVertex> points, Frustum viewField, byte[,] raster,
                                              float closest, float furthest, Vector3 curPos)
    {
        List <PointValue <byte> > result = new List <PointValue <byte> >();

        for (int i = 0; i < points.Count; i++)
        {
            Vector3    pt = points[i].point;
            ViewVector vv = viewField.ViewVec(pt);
            if (!viewField.FOV.Contains(vv))
            {
                throw new ArgumentOutOfRangeException("pt", "not contained in viewField.FOV");
            }

            /* Usual path - use sensor pixelmap
             * Vector2 coords = vv.Map<byte>(raster, viewField.FOV);
             * PointValue<byte> pv = new PointValue<byte>(pt, raster[(int)coords.x, (int)coords.y]);
             */

            // proximity path - use vertex coordinates
            Vector3 Vpos    = Vector(curPos, pt);
            float   distVal = (Vpos.magnitude - closest) / (furthest - closest);
            distVal = Mathf.Clamp01(distVal);
            byte scaledVal       = (byte)(distVal * 255f);
            PointValue <byte> pv = new PointValue <byte>(pt, scaledVal);

            // add pv to return
            result.Add(pv);
        }

        return(result);
    }
Пример #4
0
        /// <summary>
        /// Returns i,j pixel coordinates of this ViewVector within pixelGrid spanning across FOV
        /// </summary>
        public Vector2 Map <T>(T[,] grid, ViewVector FOV)
        {
            Vector2 result = new Vector2();

            result.x = (int)(grid.GetLength(0) / 2 + grid.GetLength(0) * (Theta / FOV.Theta));
            result.y = (int)(grid.GetLength(1) / 2 + grid.GetLength(1) * (Phi / FOV.Phi));
            return(result);
        }
Пример #5
0
 public Occlusion(int i, int j, ViewVector myFOV)
 {
     FOV         = myFOV;
     objSize     = -1f;
     objDistance = -1f;
     grid        = new OcclusionCell[i, j];
     Reset();
 }
Пример #6
0
        public void Update(Vector3 position)
        {
            base.Update();

            ViewVector = Vector3.Transform(Target - position, Matrix.CreateRotationY(0));
            ViewVector.Normalize();
            Forward.Normalize();
            View = Matrix.CreateLookAt(position, position + Forward, Vector3.Up);
        }
Пример #7
0
    /// <summary>
    /// Determines the required grid size given hard-coded parameters for occlusion approximation via closest in grid.
    /// </summary>
    public static Vector2 GridSize(ViewVector FOV)
    {
        float totalViewSizeX = 2.0f * ObjDistance * (float)Math.Tan(DegToRad(FOV.Theta) / 2.0);
        float totalViewSizeY = 2.0f * ObjDistance * (float)Math.Tan(DegToRad(FOV.Phi) / 2.0);

        Vector2 dims = new Vector2();

        dims.x = (int)Math.Round(totalViewSizeX / ObjSize);
        dims.y = (int)Math.Round(totalViewSizeY / ObjSize);
        return(dims);
    }
Пример #8
0
    /// <summary>
    /// Projects raster values onto passed list of points from frustum viewField.
    /// Also updates mesh colors of meshes and points defined by meshList, meshIndices, pointIndices
    /// according to color1 to color2, value1 to value2 scale.
    /// </summary>
    private List <PointValue <byte> > Project(List <CachedVertex> points, Frustum viewField, byte[,] raster,
                                              ReadOnlyCollection <SpatialMappingSource.SurfaceObject> meshList,
                                              Color32 color1, Color32 color2, Color32 defaultColor, byte value1, byte value2)
    {
        List <PointValue <byte> > result = new List <PointValue <byte> >();

        // setup coloring
        List <List <Color32> > newColoring  = new List <List <Color32> >();
        List <int>             colorIndices = new List <int>();

        for (int i = 0; i < points.Count; i++)
        {
            // setup coloring
            if (!colorIndices.Contains(points[i].meshIndex))
            {
                int            numVerts  = meshList[points[i].meshIndex].Filter.sharedMesh.vertexCount;
                List <Color32> newColors = new List <Color32>();

                // fill in default color
                for (int j = 0; j < numVerts; j++)
                {
                    newColors.Add(defaultColor);
                }

                newColoring.Add(newColors);
                colorIndices.Add(points[i].meshIndex);
            }

            Vector3    pt = points[i].point;
            ViewVector vv = viewField.ViewVec(pt);
            if (!viewField.FOV.Contains(vv))
            {
                throw new ArgumentOutOfRangeException("pt", "not contained in viewField.FOV");
            }

            Vector2           coords = vv.Map <byte>(raster, viewField.FOV);
            PointValue <byte> pv     = new PointValue <byte>(pt, raster[(int)coords.x, (int)coords.y]);

            // add pv to return
            result.Add(pv);

            // update mesh color
            float scaleVal   = (float)(pv.Value - value1) / (float)(value2 - value1);
            int   ColorIndex = colorIndices.FindIndex(x => x == points[i].meshIndex);
            newColoring[ColorIndex][points[i].pointIndex] = Color32.Lerp(color1, color2, scaleVal);
        }

        for (int i = 0; i < colorIndices.Count; i++)
        {
            meshList[colorIndices[i]].Filter.sharedMesh.SetColors(newColoring[i]);
        }

        return(result);
    }
Пример #9
0
        /// <inheritdoc />
        public override void Update(GameTime gameTime)
        {
            CameraPosition = Distance * new Vector3((float)Math.Sin(Angle), 0, (float)Math.Cos(Angle));
            ViewVector     = Vector3.Transform(CameraTarget - CameraPosition, Matrix.CreateRotationY(0));
            ViewVector.Normalize();

            Angle += 0.002f;
            View   = Matrix.CreateLookAt(CameraPosition, CameraTarget, Vector3.UnitY);

            base.Update(gameTime);
        }
Пример #10
0
    // Use this for initialization
    void Start()
    {
        // finish setup
        FOV       = new ViewVector(TargetFOV.x, TargetFOV.y);
        ViewField = new Frustum(Camera.main.transform, FOV);
        CubeMin   = new Vector3(CubeCenter.x - CubeSize / 2f, CubeCenter.y - CubeSize / 2f,
                                CubeCenter.z - CubeSize / 2f);
        CubeMax = new Vector3(CubeCenter.x + CubeSize / 2f, CubeCenter.y + CubeSize / 2f,
                              CubeCenter.z + CubeSize / 2f);
        for (int i = 0; i < Vertices; i++)
        {
            Points.Add(RandomPoint(CubeMin, CubeMax, Rand));
        }
        Scale = new Vector3(VertexSize, VertexSize, VertexSize);
        Inter = Intersector.Instance;

        // create point markers
        Parent      = new GameObject();
        Parent.name = "VertexMarkers";
        for (int i = 0; i < Vertices; i++)
        {
            GameObject Child = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            Child.AddComponent <MeshFilter>();
            Child.AddComponent <MeshRenderer>();
            Child.AddComponent <SphereCollider>();
            Child.name                 = "Marker" + i.ToString();
            Child.transform.parent     = Parent.transform;
            Child.transform.position   = Points[i];
            Child.transform.localScale = Scale;
            Child.GetComponent <MeshRenderer>().material = OutViewMaterial;

            if (ViewVectorLabels)
            {
                GameObject VVLabelT = Instantiate(VVLabelText);
                VVLabelT.transform.parent   = Parent.transform;
                VVLabelT.name               = "Text" + i.ToString();
                VVLabelT.transform.position = Points[i] + VVLabelOffset;
                GameObject VVLabelB = Instantiate(VVLabelBackground);
                VVLabelB.transform.parent   = Parent.transform;
                VVLabelB.name               = "Background" + i.ToString();
                VVLabelB.transform.position = Points[i] + VVLabelOffset + new Vector3(0, 0, 0.01f);
            }
        }

        // draw bounds box
        GameObject BoxParent = new GameObject();

        BoxParent.name = "BoxParent";
        DrawBox(CubeMin, CubeMax, BoxParent, LineSize, LineMaterial);
    }
Пример #11
0
    /// <summary>
    /// Determines the required grid size given hard-coded parameters for occlusion approximation via closest in grid.
    /// </summary>
    public Dictionary <string, int> RequiredGrid(ViewVector FOV)
    {
        double size     = 0.10; // minimum object size to not be considered occluded (m)
        double angle    = 45.0; // maximum surface angle with line-of-sight normal to not be considered occluded (deg)
        double distance = 3.0;  // maximum object distance from sensor to not be considered occluded (m)

        double apparentSize   = size * Math.Cos(DegToRad(angle));
        double totalViewSizeX = 2.0 * distance * Math.Tan(DegToRad(FOV.Theta) / 2.0);
        double totalViewSizeY = 2.0 * distance * Math.Tan(DegToRad(FOV.Phi) / 2.0);

        Dictionary <string, int> pixels = new Dictionary <string, int>();

        pixels.Add("i", (int)Math.Round(totalViewSizeX / apparentSize));
        pixels.Add("j", (int)Math.Round(totalViewSizeY / apparentSize));
        return(pixels);
    }
Пример #12
0
    /// <summary>
    /// Returns list of PointValues representing raster values projected onto points from viewField.
    /// </summary>
    private List <PointValue <T> > Project <T>(List <Vector3> points, Frustum viewField, T[,] raster)
    {
        List <PointValue <T> > result = new List <PointValue <T> >();

        foreach (Vector3 pt in points)
        {
            ViewVector vv = viewField.ViewVec(pt);
            if (!viewField.FOV.Contains(vv))
            {
                throw new ArgumentOutOfRangeException("pt", "not contained in viewField.FOV");
            }

            Vector2 coords = vv.Map <T>(raster, viewField.FOV);
            result.Add(new PointValue <T>(pt, raster[(int)coords.x, (int)coords.y]));
        }
        return(result);
    }
Пример #13
0
        public Occlusion(float myObjSize, float myObjDistance, ViewVector myFOV)
        {
            // set data
            objSize     = myObjSize;
            objDistance = myObjDistance;
            FOV         = myFOV;

            // calculate necessary pixel counts
            float   totalViewSizeX = 2.0f * objDistance * (float)Math.Tan(DegToRad(FOV.Theta) / 2.0);
            float   totalViewSizeY = 2.0f * objDistance * (float)Math.Tan(DegToRad(FOV.Phi) / 2.0);
            Vector2 dims           = new Vector2();

            dims.x = (int)Math.Round(totalViewSizeX / objSize);
            dims.y = (int)Math.Round(totalViewSizeY / objSize);

            // create grid
            grid = new OcclusionCell[(int)dims.x, (int)dims.y];
            Reset();
        }
Пример #14
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 <ViewVector> VV, out List <Vector3> PVecs)
    {
        /// setup
        VerticesInView = 0;
        InView         = new List <Vector3>();
        OutView        = new List <Vector3>();
        VV             = new List <ViewVector>();
        PVecs          = 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)
            {
                VerticesInView++;
                InView.Add(vertices[i]);
            }
            else
            {
                OutView.Add(vertices[i]);
            }
        }
        InViewCount  = InView.Count;
        OutViewCount = OutView.Count;
    }
Пример #15
0
    /// <summary>
    /// Projects raster values onto passed list of points from frustum viewField.
    /// Also updates mesh colors of meshes and points defined by meshList, meshIndices, pointIndices
    /// according to color1 to color2, value1 to value2 scale.
    /// </summary>
    private List <PointValue <byte> > Project(List <CachedVertex> points, Frustum viewField, byte[,] raster)
    {
        List <PointValue <byte> > result = new List <PointValue <byte> >();

        for (int i = 0; i < points.Count; i++)
        {
            Vector3    pt = points[i].point;
            ViewVector vv = viewField.ViewVec(pt);
            if (!viewField.FOV.Contains(vv))
            {
                throw new ArgumentOutOfRangeException("pt", "not contained in viewField.FOV");
            }

            Vector2           coords = vv.Map <byte>(raster, viewField.FOV);
            PointValue <byte> pv     = new PointValue <byte>(pt, raster[(int)coords.x, (int)coords.y]);

            // add pv to return
            result.Add(pv);
        }

        return(result);
    }
Пример #16
0
        public Occlusion(float myObjSize, float myObjDistance, ViewVector myFOV)
        {
            // control
            // Converts real size myObjSize to apparent size for up to this angle from plane perpindicular to line of sight
            float ObjAngleOffset = 30; // deg

            // set data
            objSize     = myObjSize * (float)Math.Cos(DegToRad(ObjAngleOffset));
            objDistance = myObjDistance;
            FOV         = myFOV;

            // calculate necessary pixel counts
            float   totalViewSizeX = 2.0f * objDistance * (float)Math.Tan(DegToRad(FOV.Theta) / 2.0);
            float   totalViewSizeY = 2.0f * objDistance * (float)Math.Tan(DegToRad(FOV.Phi) / 2.0);
            Vector2 dims           = new Vector2();

            dims.x = (int)Math.Round(totalViewSizeX / objSize);
            dims.y = (int)Math.Round(totalViewSizeY / objSize);

            // create grid
            grid = new OcclusionCell[(int)dims.x, (int)dims.y];
            Reset();
        }
Пример #17
0
    /// <summary>
    /// Projects raster values onto passed list of points from frustum viewField.
    /// Also updates mesh colors of meshes and points defined by meshList, meshIndices, pointIndices
    /// according to color1 to color2, value1 to value2 scale.
    /// </summary>
    private List <PointValue <byte> > Project(List <CachedVertex> points, Frustum viewField, byte[] raster,
                                              int height, int width, float closest, float furthest, Vector3 curPos, Vector2 FOVReduction, bool proxConfig)
    {
        List <PointValue <byte> > result = new List <PointValue <byte> >();

        for (int i = 0; i < points.Count; i++)
        {
            Vector3    pt = points[i].point;
            ViewVector vv = viewField.ViewVec(pt);
            if (!viewField.FOV.Contains(vv))
            {
                throw new ArgumentOutOfRangeException("pt", "not contained in viewField.FOV");
            }

            PointValue <byte> pv;

            if (!proxConfig)
            {
                // external sensor configuration
                int index = vv.Map <byte>(raster, height, width, viewField.FOV, FOVReduction);
                pv = new PointValue <byte>(pt, raster[index]);
            }
            else
            {
                // proximity sensor configuration
                byte colorVal = (byte)Mathf.Clamp(255f * (Vector(curPos, pt).magnitude - closest) / (furthest - closest),
                                                  0, 255);
                pv = new PointValue <byte>(pt, colorVal);
            }

            // add pv to return
            result.Add(pv);
        }

        return(result);
    }
Пример #18
0
 static string viewVectorToStr(ViewVector vector)
 {
     return(String.Format("(Theta: {0}, Phi: {1})", vector.Theta, vector.Phi));
 }
Пример #19
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);
    }
Пример #20
0
 /// <summary>
 /// True if vv is contained within FOV defined by this obj.
 /// </summary>
 public bool Contains(ViewVector vv)
 {
     return(Math.Abs(vv.Theta) < Theta / 2.0 && Math.Abs(vv.Phi) < Phi / 2.0);
 }
Пример #21
0
    /// <summary>
    /// Returns true if any of points are within ViewField, or a pair span it.
    /// Spanning referes to a pair of points located in front of the sensor and in diagonal ViewVector quandrants.
    /// DOES NOT update metadata.
    /// </summary>
    public bool AnyInView(List <Vector3> points, Frustum viewField)
    {
        bool topRight = false;
        bool topLeft  = false;
        bool botLeft  = false;
        bool botRight = false;
        bool left     = false;
        bool right    = false;
        bool top      = false;
        bool bot      = false;

        foreach (Vector3 pt in points)
        {
            ViewVector vv = viewField.ViewVec(pt);

            // check in in FOV
            if (viewField.FOV.Contains(vv))
            {
                return(true);
            }

            // check if elligible for span
            if (Math.Abs(vv.Theta) < 90)
            {
                // check corners
                if (vv.Theta > 0 && vv.Phi > 0)
                {
                    topRight = true;
                }
                else if (vv.Theta > 0)
                {
                    botRight = true;
                }
                else if (vv.Phi > 0)
                {
                    topLeft = true;
                }
                else
                {
                    botLeft = true;
                }

                // check edges
                if (vv.Theta > 0 && Math.Abs(vv.Phi) < viewField.FOV.Phi / 2)
                {
                    right = true;
                }
                else if (vv.Theta < 0 && Math.Abs(vv.Phi) < viewField.FOV.Phi / 2)
                {
                    left = true;
                }
                else if (vv.Phi > 0 && Math.Abs(vv.Theta) < viewField.FOV.Theta / 2)
                {
                    top = true;
                }
                else if (vv.Phi < 0 && Math.Abs(vv.Theta) < viewField.FOV.Theta / 2)
                {
                    bot = true;
                }
            }
        }

        // check for spanning
        if ((topRight && botLeft) || (topLeft && botRight))
        {
            return(true);
        }
        if ((left && right) || (top & bot))
        {
            return(true);
        }

        return(false);
    }
Пример #22
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;
    }
Пример #23
0
 public Frustum(UnityEngine.Transform myTransform, ViewVector myFOV)
 {
     Transform = myTransform;
     FOV       = myFOV;
 }
Пример #24
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);
    }
Пример #25
0
 public Frustum(Transform myTransform, ViewVector myFOV)
 {
     Transform = myTransform;
     FOV       = myFOV;
 }
Пример #26
0
    // Tests Intersector class
    // Currently tests:
    // Vector (T1)
    // InverseTransformVector (T2 - not implemented)
    // ViewVector alt. constructor (T3)
    // Intersection (small scale) (T4 - not implemented)
    // Intersection (large scale) (T5 - not implemented)
    static string TestIntersector(Intersector IntersectorObj)
    {
        string output = "\n<size=144>Testing Intersector...</size>\n\n";

        // Test 1: Vector from two points
        output += "<b>Test 1</b>\n";
        Vector3 p1 = new Vector3(0, 0, 0);
        Vector3 p2 = new Vector3(2, 2, 2);

        output += String.Format("Vector from two points: {0} to {1}\n", pointToStr(p1), pointToStr(p2));
        Vector3 result = new Vector3();

        IntersectorObj.Vector(p1, p2, ref result);
        output += String.Format("Resultant vector: {0}\n\n", pointToStr(result));

        // Cannot test Unity Library outside of Unity...
        // Test 2: InverseTransformVector
        output += "<b>Test 2</b>\n";
        GameObject view2 = new GameObject();

        view2.name = "ViewFieldTest2";
        view2.transform.Rotate(new Vector3(90, 90, 0));
        output += String.Format("InverseTransformVector... view-field position: {0}, view-field euler angles: {1}\n",
                                pointToStr(view2.transform.position), pointToStr(view2.transform.eulerAngles));
        Vector3[] unitVectors = unitVectorsArray();
        for (int i = 0; i < 8; i++)
        {
            output += String.Format("Vector{0}: World Space: {1}, View-Field Local Space: {2}\n",
                                    i + 1, pointToStr(unitVectors[i]), pointToStr(view2.transform.InverseTransformVector(unitVectors[i])));
        }
        output += "\n";
        // */

        // Test 3: View Vector alt. constructor
        output += "<b>Test 3</b>\n";
        output += String.Format("ViewVector creation from position vector (in local space)... 2D cross-sectional plane is XY plane.\n");
        Vector3 forward = new Vector3(0, 0, 1);

        for (int i = 0; i < 8; i++)
        {
            output += String.Format("Vector{0} {1}: ViewVector{0} (deg): {2}\n",
                                    i + 1, pointToStr(unitVectors[i]), viewVectorToStr(new ViewVector(unitVectors[i])));
        }
        output += String.Format("Vector {0}: ViewVector (deg): {1}\n",
                                pointToStr(forward), viewVectorToStr(new ViewVector(forward)));
        output += "\n";

        // Cannot test Unity Library outside of Unity...
        // Test 4: Intersection (small scale)
        output += "<b>Test 4</b>\n";
        List <Vector3> unitVectorList = new List <Vector3>();

        for (int i = 0; i < 8; i++)
        {
            unitVectorList.Add(unitVectors[i]);
        }
        GameObject view4 = new GameObject();

        view4.name = "ViewFieldTest4";
        ViewVector FOV4        = new ViewVector(170, 170);
        Frustum    projection4 = new Frustum(view4.transform, FOV4);

        byte[,] raster4 = new byte[100, 100];
        output         += String.Format("Intersection... Raster: ({0}x{1}), Frustum FOV: ({2}x{3}), " +
                                        "Frustum Pos: {4}, Frustum EA's: {5}\n" +
                                        "Tested all 8 unit vectors, found intersection points...\n",
                                        raster4.GetLength(0), raster4.GetLength(1), FOV4.Theta, FOV4.Phi,
                                        pointToStr(projection4.Transform.position), pointToStr(projection4.Transform.eulerAngles));
        List <PointValue <byte> > intersect = Intersector.Instance.Intersection(projection4, raster4, unitVectorList);

        foreach (PointValue <byte> pv in intersect)
        {
            output += String.Format("Point: {0}, ViewVector: {1}\n",
                                    pointToStr(pv.Point), viewVectorToStr(new ViewVector(pv.Point)));
        }
        output += "\n";


        // Cannot test Unity Library outside of Unity...
        // Test 5: Intersection (large scale)
        output += "<b>Test 5</b>\n";
        System.Random rand  = new System.Random();
        GameObject    view5 = new GameObject();

        view5.name = "ViewFieldTest5";
        ViewVector FOV5        = new ViewVector(179, 179);
        Frustum    projection5 = new Frustum(view5.transform, FOV5);

        byte[,] raster5 = new byte[100, 100];
        int            iterations  = 100;
        Stopwatch      stopWatch   = new Stopwatch();
        Vector3        boundsMin   = new Vector3(-5, -5, -5);
        Vector3        boundsMax   = new Vector3(5, 5, 5);
        List <Vector3> randVectors = new List <Vector3>();

        for (int i = 0; i < iterations; i++)
        {
            randVectors.Add(randomPoint(boundsMin, boundsMax, rand));
        }
        output += String.Format("Intersection... Raster: ({0}x{1}), Frustum FOV: ({2}x{3}). {4} Iterations...\n",
                                raster5.GetLength(0), raster5.GetLength(1), FOV5.Theta, FOV5.Phi, randVectors.Count);
        Intersector tmp = Intersector.Instance;

        stopWatch.Reset();
        stopWatch.Start();
        List <PointValue <byte> > result5 = tmp.Intersection(projection5, raster5, randVectors);

        stopWatch.Stop();
        long ms = (long)1000 * stopWatch.ElapsedTicks / Stopwatch.Frequency;

        output += String.Format("Took {0} ms ({1} us / op)... {2} vectors in view\n", ms,
                                ms / (double)iterations * 1000.0, result5.Count);
        output += "\n";

        // Test 6: RequiredGrid
        output += "<b>Test 6</b>\n";
        ViewVector FOV6 = new ViewVector(60, 60);

        output += String.Format("Testing RequiredGrid... FOV: {0}\n", viewVectorToStr(FOV6));
        Dictionary <string, int> pixels = Intersector.Instance.RequiredGrid(FOV6);

        output += String.Format("i: {0}, j: {1}\n", pixels["i"], pixels["j"]);
        output += "\n";

        /// Test 7: Occlusion (basic)
        output += "<b>Test 7</b>\n";
        GameObject view7 = new GameObject();

        view7.name = "ViewFieldTest7";
        ViewVector FOV7        = new ViewVector(170, 170);
        Frustum    projection7 = new Frustum(view7.transform, FOV7);

        byte[,] raster7 = new byte[100, 100];
        for (int i = 0; i < raster7.GetLength(0); i++)
        {
            for (int j = 0; j < raster7.GetLength(1); j++)
            {
                raster7[i, j] = (byte)(i + j);
            }
        }
        output += String.Format("Created Frustum: pos: {0}, EA's {1}, FOV: {2}\n",
                                pointToStr(projection7.Transform.position), pointToStr(projection7.Transform.eulerAngles),
                                viewVectorToStr(projection7.FOV));
        output += String.Format("Created Raster: {0}x{1}\n", raster7.GetLength(0), raster7.GetLength(1));
        Vector3        v1        = new Vector3(1, 1, 1);
        Vector3        v2        = new Vector3(2, 2, 2);
        Vector3        v3        = new Vector3(0, 0, 1);
        List <Vector3> vertices7 = new List <Vector3>();

        vertices7.Add(v2);
        vertices7.Add(v1);
        vertices7.Add(v2);
        vertices7.Add(v3);
        output += String.Format("Trying vertices: v1: {0}, v2: {1}, v3: {2}. Intersection return...\n",
                                pointToStr(v1), pointToStr(v2), pointToStr(v3));
        List <PointValue <byte> > intersectRet = Intersector.Instance.Intersection(projection7, raster7, vertices7);

        for (int i = 0; i < intersectRet.Count; i++)
        {
            output += String.Format("Point: {0}, Value: {1}\n",
                                    pointToStr(intersectRet[i].Point), intersectRet[i].Value);
        }
        output += "\n";

        // Test 8: Occlusion (large scale)
        output += "<b>Test 8</b>\n";
        GameObject view8 = new GameObject();

        view8.name = "ViewFieldTest8";
        ViewVector FOV8        = new ViewVector(170, 170);
        Frustum    projection8 = new Frustum(view8.transform, FOV8);

        byte[,] raster8 = new byte[100, 100];
        output         += String.Format("Created Frustum: pos: {0}, EA's {1}, FOV: {2}\n",
                                        pointToStr(projection8.Transform.position), pointToStr(projection8.Transform.eulerAngles),
                                        viewVectorToStr(projection8.FOV));
        output += String.Format("Created Raster: {0}x{1}\n", raster8.GetLength(0), raster8.GetLength(1));
        // create 'wall' vertices
        double         wallSize     = 4.0;
        double         wallRes      = 0.05;
        double         wallDistance = 3.0;
        float          wallWiggle   = 0.001f;
        int            wallPixels   = (int)(wallSize / wallRes);
        double         wallBotLeft  = -(wallSize / 2.0);
        int            wallValue    = 0;
        int            wallCount    = (int)Math.Pow(wallPixels, 2);
        List <Vector3> vertices     = new List <Vector3>();

        for (int i = 0; i < wallPixels; i++)
        {
            for (int j = 0; j < wallPixels; j++)
            {
                float   vertX = (float)(i * wallRes + wallBotLeft);
                float   vertY = (float)(j * wallRes + wallBotLeft);
                float   vertZ = (float)wallDistance;
                Vector3 vert  = new Vector3(vertX, vertY, vertZ);
                vertices.Add(wiggleVert(vert, wallWiggle, rand));
            }
        }
        // create 'box' vertices
        float   boxSize  = 1f;
        Vector3 boxMin   = new Vector3(-boxSize / 2, -boxSize / 2, (float)(wallDistance + 1));
        Vector3 boxMax   = new Vector3(boxSize / 2, boxSize / 2, (float)(wallDistance + 1 + boxSize));
        int     boxCount = 10000;

        for (int i = 0; i < boxCount; i++)
        {
            vertices.Add(randomPoint(boxMin, boxMax, rand));
        }
        // report progress
        output += String.Format("Created wall... ({0},{0}) to ({1},{1}), z: {2}, wiggle: {3}, " +
                                "vertices: {4}, resolution (m): {5}\n",
                                wallBotLeft, wallBotLeft + wallSize, wallDistance, wallWiggle, wallCount, wallRes);
        output += String.Format("Created box: {0} to {1}, vertices: {2}\n",
                                pointToStr(boxMin), pointToStr(boxMax), boxCount);
        // run intersection
        List <PointValue <byte> > intersectRet8 = Intersector.Instance.Intersection(projection8, raster8, vertices);
        int wallCountRet = 0;
        int boxCountRet  = 0;

        for (int i = 0; i < intersectRet8.Count; i++)
        {
            Vector3 point = intersectRet8[i].Point;
            if (within(point, boxMin, boxMax))
            {
                boxCountRet++;
            }
            else
            {
                wallCountRet++;
            }
        }
        output += String.Format("Intersection Return... wall vertices: {0}/{1}, box vertices: {2}/{3}",
                                wallCountRet, wallCount, boxCountRet, boxCount);

        return(output);
    }
Пример #27
0
 private static string viewVectorToStr(ViewVector vector)
 {
     return(String.Format("(Theta: {0}, Phi: {1})", Math.Round(vector.Theta, 0), Math.Round(vector.Phi, 0)));
 }