public override string ToString()
        {
            StringBuilder sb = new StringBuilder();

            sb.Append('{');

            WriteName(sb, "V0");
            sb.Append(V0.ToString() + ",");
            WriteName(sb, "V1");
            sb.Append(V1.ToString() + ",");
            WriteName(sb, "V2");
            sb.Append(V2.ToString() + ",");
            WriteName(sb, "V3");
            sb.Append(V3.ToString() + ",");
            WriteName(sb, "V4");
            sb.Append(V4.ToString() + ",");
            WriteName(sb, "V5");
            sb.Append(V5.ToString() + ",");
            WriteName(sb, "V6");
            sb.Append(V6.ToString() + ",");
            WriteName(sb, "V7");
            sb.Append(V7.ToString() + ",");
            WriteName(sb, "V8");
            sb.Append(V8.ToString() + ",");
            WriteName(sb, "V9");
            sb.Append(V9.ToString() + ",");
            sb.Length--;

            sb.Append('}');
            return(sb.ToString());
        }
Пример #2
0
    public void Execute(int index)
    {
        V6      level1          = SeenMPC3Table[Seen_MPC3[index]];
        Vector3 point_to_level1 = (level1.Coordinates - Point).normalized;
        float   distance1       = (level1.Coordinates - Point).magnitude;

        int temp_index = Mathf.FloorToInt(index / MaxListsLength);
        int temp_i     = index - temp_index * MaxListsLength;

        if (temp_i <= LookUpTable3ID[Seen_MPC3[index]].y - LookUpTable3ID[Seen_MPC3[index]].x)
        {
            int temp_l = LookUpTable3ID[Seen_MPC3[index]].x + temp_i;
            // defining the second level of points
            V6      level2           = SeenMPC3Table[LookUpTable3[temp_l].MPCIndex];
            Vector3 level2_to_level1 = (level1.Coordinates - level2.Coordinates).normalized;

            // we define a perpendicular direction to the normal of the level1
            Vector3 normal1 = level1.Normal;
            Vector3 n_perp1 = new Vector3(-normal1.z, 0, normal1.x);

            if ((Vector3.Dot(n_perp1, point_to_level1) * Vector3.Dot(n_perp1, level2_to_level1)) < 0)
            {
                double theta1 = Math.Acos(Vector3.Dot(normal1, -point_to_level1));
                double theta2 = Math.Acos(Vector3.Dot(normal1, -level2_to_level1));
                int    I1, I2, I3;
                if (theta1 + theta2 < 0.35)
                {
                    I1 = 0;
                }
                else
                {
                    I1 = 1;
                }
                if (theta1 < 1.22)
                {
                    I2 = 0;
                }
                else
                {
                    I2 = 1;
                }
                if (theta2 < 1.22)
                {
                    I3 = 0;
                }
                else
                {
                    I3 = 1;
                }

                float angular_gain = Seen_MPC3_att[index] * (float)Math.Exp(-12 * ((theta1 + theta2 - 0.35) * I1 + (theta1 - 1.22) * I2 + (theta2 - 1.22) * I3));

                float     distance2      = (level1.Coordinates - level2.Coordinates).magnitude;
                float     distance       = distance1 + distance2;
                Path3Half temp_Path3Half = new Path3Half(Point, level1.Coordinates, SeenMPC3Table[LookUpTable3[temp_l].MPCIndex].Coordinates, LookUpTable3[temp_l].MPCIndex, distance, angular_gain);
                ReachableHalfPath3[index] = temp_Path3Half;
            }
        }
    }
 // Use this for initialization
 void Start()
 {
     if (BuyCarScript.V01A == 0)
     {
         BuyCarScript.V01A = 2;
     }
     if (BuyCarScript.V01A == 2)
     {
         V1.SetActive(true);
     }
     if (BuyCarScript.V02A == 2)
     {
         V2.SetActive(true);
     }
     if (BuyCarScript.V03A == 2)
     {
         V3.SetActive(true);
     }
     if (BuyCarScript.V04A == 2)
     {
         V4.SetActive(true);
     }
     if (BuyCarScript.V05A == 2)
     {
         V5.SetActive(true);
     }
     if (BuyCarScript.V06A == 2)
     {
         V6.SetActive(true);
     }
     if (BuyCarScript.V07A == 2)
     {
         V7.SetActive(true);
     }
     if (BuyCarScript.V08A == 2)
     {
         V8.SetActive(true);
     }
     if (BuyCarScript.V09A == 2)
     {
         V9.SetActive(true);
     }
     if (BuyCarScript.V10A == 2)
     {
         V10.SetActive(true);
     }
     car = true;
 }
    // function that searches for the most left bottom vertex to define the start and end points of the building's ground polygon
    void Search_for_LeftBottom(List <V6> valid_vrtx_nrml, out V6 lb_start, out V6 lb_end)
    {
        var SortedByX = valid_vrtx_nrml.OrderBy(xx => xx.Coordinates.x).ToList();

        // several of vertices may have the same X value among which we need to choose the most left
        var list_min_by_x = new List <V6>();
        int i             = 1;

        list_min_by_x.Add(SortedByX[0]);
        while (SortedByX[0].Coordinates == SortedByX[i].Coordinates)
        {
            list_min_by_x.Add(SortedByX[i]);
            i += 1;
        }
        if (i == 1)
        {
            Debug.Log("WARNING! Something wrong: the most left bottom vertex has to have two normals");
            lb_start = new V6(new Vector3(0, 0, 0), new Vector3(0, 0, 0));
            lb_end   = new V6(new Vector3(0, 0, 0), new Vector3(0, 0, 0));
            return;
        }


        // searching for the most bottom and left vertex in the building's bottom polygon
        var SortedByZ = list_min_by_x.OrderByDescending(zz => zz.Coordinates.z).ToList();

        // shity assigning of the values, I do not understand it yet
        lb_start = new V6(new Vector3(0, 0, 0), new Vector3(0, 0, 0));
        lb_end   = new V6(new Vector3(0, 0, 0), new Vector3(0, 0, 0));

        // defining the start and end vertices
        if (SortedByZ[0].Coordinates == SortedByZ[1].Coordinates)
        {
            if (SortedByZ[0].Normal.z > SortedByZ[1].Normal.z)
            {
                lb_start = SortedByZ[0];
                lb_end   = SortedByZ[1];
            }
            else
            {
                lb_start = SortedByZ[1];
                lb_end   = SortedByZ[0];
            }
        }
    }
Пример #5
0
    public void Execute(int index)
    {
        OutputDelays[index]     = 0;
        OutputAmplitudes[index] = 0;

        V6 level1 = SeenMPC2Table[Rx_MPC2Array[index]];

        float distance1 = (level1.Coordinates - Rx_Position).magnitude;

        int temp_index = Mathf.FloorToInt(index / MaxListsLength);
        int temp_i     = index - temp_index * MaxListsLength;

        if (temp_i <= LookUpTable2ID[Rx_MPC2Array[index]].y - LookUpTable2ID[Rx_MPC2Array[index]].x)
        {
            int temp_l = LookUpTable2ID[Rx_MPC2Array[index]].x + temp_i;

            V6      level2           = SeenMPC2Table[LookUpTable2[temp_l].MPCIndex];
            Vector3 level2_to_level1 = (level1.Coordinates - level2.Coordinates).normalized;
            float   distance2        = (level1.Coordinates - level2.Coordinates).magnitude;

            // check if level2 is seen by Tx
            int   existence_flag = 0;
            float Tx_att         = 0f;
            for (int i = 0; i < Tx_MPC2.Length; i++)
            {
                if (LookUpTable2[temp_l].MPCIndex == Tx_MPC2[i])
                {
                    existence_flag = 1;
                    Tx_att         = Tx_MPC2_att[i];
                    break;
                }
            }

            if (existence_flag == 1)
            {
                Vector3 normal1      = level1.Normal;
                Vector3 n_perp1      = new Vector3(-normal1.z, 0, normal1.x);
                Vector3 Rx_to_level1 = (level1.Coordinates - Rx_Position).normalized;

                Vector3 normal2      = level2.Normal;
                Vector3 n_perp2      = new Vector3(-normal2.z, 0, normal2.x);
                Vector3 level2_to_Tx = (Tx_Position - level2.Coordinates).normalized;

                // check if the two vectors come from different sides of the normal
                if ((Vector3.Dot(n_perp2, level2_to_level1) * Vector3.Dot(n_perp2, level2_to_Tx) < 0) && (Vector3.Dot(n_perp1, level2_to_level1) * Vector3.Dot(n_perp1, Rx_to_level1) < 0))
                {
                    double theta11 = Math.Acos(Vector3.Dot(normal1, -Rx_to_level1));
                    double theta12 = Math.Acos(Vector3.Dot(normal1, -level2_to_level1));
                    int    I11, I12, I13;
                    if (theta11 + theta12 < 0.35)
                    {
                        I11 = 0;
                    }
                    else
                    {
                        I11 = 1;
                    }
                    if (theta11 < 1.22)
                    {
                        I12 = 0;
                    }
                    else
                    {
                        I12 = 1;
                    }
                    if (theta12 < 1.22)
                    {
                        I13 = 0;
                    }
                    else
                    {
                        I13 = 1;
                    }

                    float angular_gain1 = (float)Math.Exp(-12 * ((theta11 + theta12 - 0.35) * I11 + (theta11 - 1.22) * I12 + (theta12 - 1.22) * I13));

                    double theta21 = Math.Acos(Vector3.Dot(normal2, level2_to_Tx));
                    double theta22 = Math.Acos(Vector3.Dot(normal1, level2_to_level1));
                    int    I21, I22, I23;
                    if (theta21 + theta22 < 0.35)
                    {
                        I21 = 0;
                    }
                    else
                    {
                        I21 = 1;
                    }
                    if (theta21 < 1.22)
                    {
                        I22 = 0;
                    }
                    else
                    {
                        I22 = 1;
                    }
                    if (theta22 < 1.22)
                    {
                        I23 = 0;
                    }
                    else
                    {
                        I23 = 1;
                    }

                    float angular_gain2 = (float)Math.Exp(-12 * ((theta21 + theta22 - 0.35) * I21 + (theta21 - 1.22) * I22 + (theta22 - 1.22) * I23));

                    float angular_gain = angular_gain1 * angular_gain2;

                    float distance3  = level2_to_Tx.magnitude;
                    float distance   = distance1 + distance2 + distance3;
                    Path2 temp_path2 = new Path2(Rx_Position, level1.Coordinates, level2.Coordinates, Tx_Position, distance, angular_gain);
                    SecondOrderPaths[index] = temp_path2;

                    OutputDelays[index]     = distance;// / Speed_of_Light;
                    OutputAmplitudes[index] = Tx_att * Rx_MPC2Array_att[index] * angular_gain * (float)Math.Pow(1 / distance, 2);
                }
            }
        }
    }
 public void Left()
 {
     if (V2.activeInHierarchy == true)
     {
         V1.SetActive(true);    V2.SetActive(false);   V3.SetActive(false);   V4.SetActive(false);   V5.SetActive(false);   V6.SetActive(false);   V7.SetActive(false);   V8.SetActive(false);   V9.SetActive(false);   V10.SetActive(false);
     }
     else if (V3.activeInHierarchy == true)
     {
         V1.SetActive(false);   V2.SetActive(true);    V3.SetActive(false);   V4.SetActive(false);   V5.SetActive(false);   V6.SetActive(false);   V7.SetActive(false);   V8.SetActive(false);   V9.SetActive(false);   V10.SetActive(false);
     }
     else if (V4.activeInHierarchy == true)
     {
         V1.SetActive(false);   V2.SetActive(false);   V3.SetActive(true);    V4.SetActive(false);   V5.SetActive(false);   V6.SetActive(false);   V7.SetActive(false);   V8.SetActive(false);   V9.SetActive(false);   V10.SetActive(false);
     }
     else if (V5.activeInHierarchy == true)
     {
         V1.SetActive(false);   V2.SetActive(false);   V3.SetActive(false);   V4.SetActive(true);    V5.SetActive(false);   V6.SetActive(false);   V7.SetActive(false);   V8.SetActive(false);   V9.SetActive(false);   V10.SetActive(false);
     }
     else if (V6.activeInHierarchy == true)
     {
         V1.SetActive(false);   V2.SetActive(false);   V3.SetActive(false);   V4.SetActive(false);   V5.SetActive(true);    V6.SetActive(false);   V7.SetActive(false);   V8.SetActive(false);   V9.SetActive(false);   V10.SetActive(false);
     }
     else if (V7.activeInHierarchy == true)
     {
         V1.SetActive(false);   V2.SetActive(false);   V3.SetActive(false);   V4.SetActive(false);   V5.SetActive(false);   V6.SetActive(true);    V7.SetActive(false);   V8.SetActive(false);   V9.SetActive(false);   V10.SetActive(false);
     }
     else if (V8.activeInHierarchy == true)
     {
         V1.SetActive(false);   V2.SetActive(false);   V3.SetActive(false);   V4.SetActive(false);   V5.SetActive(false);   V6.SetActive(false);   V7.SetActive(true);    V8.SetActive(false);   V9.SetActive(false);   V10.SetActive(false);
     }
     else if (V9.activeInHierarchy == true)
     {
         V1.SetActive(false);   V2.SetActive(false);   V3.SetActive(false);   V4.SetActive(false);   V5.SetActive(false);   V6.SetActive(false);   V7.SetActive(false);   V8.SetActive(true);    V9.SetActive(false);   V10.SetActive(false);
     }
     else if (V10.activeInHierarchy == true)
     {
         V1.SetActive(false);   V2.SetActive(false);   V3.SetActive(false);   V4.SetActive(false);   V5.SetActive(false);   V6.SetActive(false);   V7.SetActive(false);   V8.SetActive(false);   V9.SetActive(true);    V10.SetActive(false);
     }
 }
Пример #7
0
 public V7(V6 MPC, int num)
 {
     CoordNorm = MPC;
     Number    = num;
 }
Пример #8
0
    // Start is called before the first frame update
    void Start()
    {
        GameObject           MPC_Spawner = GameObject.Find("MPC_spawner");
        Scatterers_Spawning2 MPC_Script  = MPC_Spawner.GetComponent <Scatterers_Spawning2>();
        List <Vector3>       MPC1        = MPC_Script.MPC1_possiblepositionList;
        List <Vector3>       MPC2        = MPC_Script.MPC2_possiblepositionList;
        List <Vector3>       MPC3        = MPC_Script.MPC3_possiblepositionList;

        /*
         * Debug.Log("Number of MPC1 is " + MPC1.Count);
         * for (int i = 0; i < MPC1.Count; i++)
         * {
         *  GameObject cleared_sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
         *
         *  cleared_sphere.transform.position = MPC1[i];
         *  Destroy(cleared_sphere.GetComponent<SphereCollider>()); // remove collider
         *  var sphereRenderer = cleared_sphere.GetComponent<Renderer>();
         *  sphereRenderer.material = MPC2_mat;
         *  cleared_sphere.transform.localScale = new Vector3(0.3f, 0.3f, 0.3f);
         * }
         */


        // Declaring buildings and observation points
        Buildings = GameObject.FindGameObjectsWithTag("Reflecting_Obstacles");
        // The number of observation points should not be too big, a few is enough
        Observation_Points = GameObject.FindGameObjectsWithTag("Observation_Points");
        // Define the main road direction
        Vector3 main_axis = (Observation_Points[0].transform.position - Observation_Points[1].transform.position).normalized;
        Vector3 perp_axis = new Vector3(main_axis.z, 0, -main_axis.x);

        // subset of the seen Buldings
        List <GameObject> Building_list = new List <GameObject>();

        // Going through all observation points
        for (int k = 0; k < Observation_Points.Length; k++)
        {
            // analyzing which buidings are seen
            for (int b = 0; b < Buildings.Length; b++)
            {
                Vector3[] vrtx = Buildings[b].GetComponent <MeshFilter>().mesh.vertices;
                Vector3[] nrml = Buildings[b].GetComponent <MeshFilter>().mesh.normals;

                int seen_vrtx_count = 0;

                for (int v = 0; v < vrtx.Length; v++)
                {
                    if (vrtx[v].y == 0)
                    {
                        if (!Physics.Linecast(Observation_Points[k].transform.position, vrtx[v] + 1.1f * nrml[v]))
                        {
                            seen_vrtx_count += 1;
                        }
                    }
                }
                if (seen_vrtx_count != 0)
                {
                    if (!Building_list.Contains(Buildings[b]))
                    {
                        Building_list.Add(Buildings[b]);
                    }
                }
            }
        }

        // deactivating nonseen buildings
        for (int b = 0; b < Buildings.Length; b++)
        {
            if (!Building_list.Contains(Buildings[b]))
            {
                Buildings[b].SetActive(false);
            }
        }
        Debug.Log("The number of seen Buildings = " + Building_list.Count);

        List <Vector3> GlobalMPC1 = new List <Vector3>();

        List <Vector3> GlobalMPC2 = new List <Vector3>();

        List <Vector3> GlobalMPC3 = new List <Vector3>();

        // analyzing each seen building separately
        for (int k = 0; k < Building_list.Count; k++)
        {
            // writing MPCs into a txt file
            //string writePath;
            List <string> Obj_List = new List <string>();

            Vector3[] vrtx = Building_list[k].GetComponent <MeshFilter>().mesh.vertices;
            Vector3[] nrml = Building_list[k].GetComponent <MeshFilter>().mesh.normals;

            List <Vector3> floor_vrtx = new List <Vector3>();
            List <Vector3> floor_nrml = new List <Vector3>();
            var            pairs      = new List <V6>();

            List <Vector3> possible_vrtx = new List <Vector3>();
            List <Vector3> possible_nrml = new List <Vector3>();



            for (int l = 0; l < vrtx.Length; l++)
            {
                if (vrtx[l].y == 0 && Mathf.Abs(nrml[l].y) < 0.9)
                {
                    floor_vrtx.Add(vrtx[l]);
                    floor_nrml.Add(nrml[l]);

                    // adding coordinates and normals of the vertices into a single object V6 (like a N x 6 matrix)
                    V6 valid_pair = new V6(vrtx[l], nrml[l]);
                    pairs.Add(valid_pair);
                }
            }
            // finding the edges of each building
            List <Vector3> SortedByX = floor_vrtx.OrderBy(vertex => vertex.x).ToList();
            List <Vector3> SortedByZ = floor_vrtx.OrderBy(vertex => vertex.z).ToList();
            float          x_l       = SortedByX[0].x - WW1;                   // x left
            float          x_r       = SortedByX[SortedByX.Count - 1].x + WW1; // x right
            float          z_d       = SortedByZ[0].z - WW1;                   // z down
            float          z_u       = SortedByZ[SortedByX.Count - 1].z + WW1; // z up

            // searching which scatterers are located near the building
            NearbyElements(x_l, x_r, z_d, z_u, MPC1, out List <Vector3> NeabyMPC1);
            NearbyElements(x_l, x_r, z_d, z_u, MPC2, out List <Vector3> NeabyMPC2);
            NearbyElements(x_l, x_r, z_d, z_u, MPC3, out List <Vector3> NeabyMPC3);

            //////////////////////////////////////////////////////////////////////////////////////////////////////////
            /// Defining areas around building where scatterers can be located
            //////////////////////////////////////////////////////////////////////////////////////////////////////////



            // defining necessary elements for the polygon that connects the last and the first vertices
            Vector3 n1_0 = floor_nrml[floor_vrtx.Count - 1];
            Vector3 p1_0 = floor_vrtx[floor_vrtx.Count - 1];
            Vector3 s1_0 = floor_vrtx[floor_vrtx.Count - 1] + WW1 * floor_nrml[floor_vrtx.Count - 1];

            Vector3 n2_0 = floor_nrml[0];
            Vector3 p2_0 = floor_vrtx[0];
            Vector3 s2_0 = floor_vrtx[0] + WW1 * floor_nrml[0];

            Area34 area = new Area34(p1_0, s1_0, p2_0, s2_0);
            //DrawArea(area);

            PickMPC(n1_0, p1_0, s1_0, n2_0, p2_0, s2_0, NeabyMPC1, out List <V6> MPC1_V6);
            PickMPC(n1_0, p1_0, s1_0, n2_0, p2_0, s2_0, NeabyMPC2, out List <V6> MPC2_V6);
            PickMPC(n1_0, p1_0, s1_0, n2_0, p2_0, s2_0, NeabyMPC3, out List <V6> MPC3_V6);

            //int MPC1_num = 0;
            for (int ii = 0; ii < MPC1_V6.Count; ii++)
            {
                if (!GlobalMPC1.Contains(MPC1_V6[ii].Coordinates))
                {
                    SeenV6_MPC1.Add(MPC1_V6[ii]);
                    V7 tempV7_MPC1 = new V7(MPC1_V6[ii], MPC1_num);
                    SeenV7_MPC1.Add(tempV7_MPC1);
                    GlobalMPC1.Add(MPC1_V6[ii].Coordinates);

                    GameObject cleared_sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);

                    cleared_sphere.transform.position = MPC1_V6[ii].Coordinates;
                    Destroy(cleared_sphere.GetComponent <SphereCollider>()); // remove collider
                    // cleared_sphere.name = "Building #" + k + "; mpc1 #" + MPC1_num;
                    cleared_sphere.name = "mpc1 #" + MPC1_num;
                    var sphereRenderer = cleared_sphere.GetComponent <Renderer>();
                    sphereRenderer.material             = MPC1_mat;
                    cleared_sphere.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);

                    MPC1_num += 1;
                }
            }

            //int MPC2_num = 0;
            for (int ii = 0; ii < MPC2_V6.Count; ii++)
            {
                if (!GlobalMPC2.Contains(MPC2_V6[ii].Coordinates))
                {
                    SeenV6_MPC2.Add(MPC2_V6[ii]);
                    V7 tempV7_MPC2 = new V7(MPC2_V6[ii], MPC2_num);
                    SeenV7_MPC2.Add(tempV7_MPC2);
                    GlobalMPC2.Add(MPC2_V6[ii].Coordinates);

                    GameObject cleared_sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);

                    cleared_sphere.transform.position = MPC2_V6[ii].Coordinates;
                    Destroy(cleared_sphere.GetComponent <SphereCollider>()); // remove collider
                    cleared_sphere.name = "mpc2 #" + MPC2_num;
                    var sphereRenderer = cleared_sphere.GetComponent <Renderer>();
                    sphereRenderer.material             = MPC2_mat;
                    cleared_sphere.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);

                    MPC2_num += 1;
                }
            }

            //int MPC3_num = 0;
            for (int ii = 0; ii < MPC3_V6.Count; ii++)
            {
                if (!GlobalMPC3.Contains(MPC3_V6[ii].Coordinates))
                {
                    SeenV6_MPC3.Add(MPC3_V6[ii]);
                    V7 tempV7_MPC3 = new V7(MPC3_V6[ii], MPC3_num);
                    SeenV7_MPC3.Add(tempV7_MPC3);
                    GlobalMPC3.Add(MPC3_V6[ii].Coordinates);

                    GameObject cleared_sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);

                    cleared_sphere.transform.position = MPC3_V6[ii].Coordinates;
                    Destroy(cleared_sphere.GetComponent <SphereCollider>()); // remove collider
                    cleared_sphere.name = "mpc3 #" + MPC3_num;
                    var sphereRenderer = cleared_sphere.GetComponent <Renderer>();
                    sphereRenderer.material             = MPC3_mat;
                    cleared_sphere.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);

                    MPC3_num += 1;
                }
            }



            // draw areas for all vertices
            Vector3 point1 = new Vector3(0.0f, 0.0f, 0.0f);
            Vector3 point2 = new Vector3(0.0f, 0.0f, 0.0f);
            Vector3 shift1 = new Vector3(0.0f, 0.0f, 0.0f);
            Vector3 shift2 = new Vector3(0.0f, 0.0f, 0.0f);
            for (int l = 0; l < floor_vrtx.Count - 1; l++)
            {
                point1 = floor_vrtx[l];
                point2 = floor_vrtx[l + 1];

                shift1 = floor_vrtx[l] + WW1 * floor_nrml[l];
                shift2 = floor_vrtx[l + 1] + WW1 * floor_nrml[l + 1];

                PickMPC(floor_nrml[l], point1, shift1, floor_nrml[l + 1], point2, shift2, NeabyMPC1, out List <V6> for_MPC1_V6);
                PickMPC(floor_nrml[l], point1, shift1, floor_nrml[l + 1], point2, shift2, NeabyMPC2, out List <V6> for_MPC2_V6);
                PickMPC(floor_nrml[l], point1, shift1, floor_nrml[l + 1], point2, shift2, NeabyMPC3, out List <V6> for_MPC3_V6);


                for (int ii = 0; ii < for_MPC1_V6.Count; ii++)
                {
                    if (!GlobalMPC1.Contains(for_MPC1_V6[ii].Coordinates))
                    {
                        SeenV6_MPC1.Add(for_MPC1_V6[ii]);
                        V7 tempV7_MPC1 = new V7(for_MPC1_V6[ii], MPC1_num);
                        SeenV7_MPC1.Add(tempV7_MPC1);
                        GlobalMPC1.Add(for_MPC1_V6[ii].Coordinates);

                        GameObject cleared_sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);

                        cleared_sphere.transform.position = for_MPC1_V6[ii].Coordinates;
                        Destroy(cleared_sphere.GetComponent <SphereCollider>()); // remove collider
                        cleared_sphere.name = "mpc1 #" + MPC1_num;
                        var sphereRenderer = cleared_sphere.GetComponent <Renderer>();
                        sphereRenderer.material             = MPC1_mat;
                        cleared_sphere.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);

                        MPC1_num += 1;
                    }
                }

                for (int ii = 0; ii < for_MPC2_V6.Count; ii++)
                {
                    if (!GlobalMPC2.Contains(for_MPC2_V6[ii].Coordinates))
                    {
                        SeenV6_MPC2.Add(for_MPC2_V6[ii]);
                        V7 tempV7_MPC2 = new V7(for_MPC2_V6[ii], MPC2_num);
                        SeenV7_MPC2.Add(tempV7_MPC2);
                        GlobalMPC2.Add(for_MPC2_V6[ii].Coordinates);

                        GameObject cleared_sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);

                        cleared_sphere.transform.position = for_MPC2_V6[ii].Coordinates;
                        Destroy(cleared_sphere.GetComponent <SphereCollider>()); // remove collider
                        cleared_sphere.name = "mpc2 #" + MPC2_num;
                        var sphereRenderer = cleared_sphere.GetComponent <Renderer>();
                        sphereRenderer.material             = MPC2_mat;
                        cleared_sphere.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);

                        MPC2_num += 1;
                    }
                }

                for (int ii = 0; ii < for_MPC3_V6.Count; ii++)
                {
                    if (!GlobalMPC3.Contains(for_MPC3_V6[ii].Coordinates))
                    {
                        SeenV6_MPC3.Add(for_MPC3_V6[ii]);
                        V7 tempV7_MPC3 = new V7(for_MPC3_V6[ii], MPC3_num);
                        SeenV7_MPC3.Add(tempV7_MPC3);
                        GlobalMPC3.Add(for_MPC3_V6[ii].Coordinates);

                        GameObject cleared_sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);

                        cleared_sphere.transform.position = for_MPC3_V6[ii].Coordinates;
                        Destroy(cleared_sphere.GetComponent <SphereCollider>()); // remove collider
                        cleared_sphere.name = "mpc3 #" + MPC3_num;
                        var sphereRenderer = cleared_sphere.GetComponent <Renderer>();
                        sphereRenderer.material             = MPC3_mat;
                        cleared_sphere.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);

                        MPC3_num += 1;
                    }
                }

                area = new Area34(point1, shift1, point2, shift2);
                //DrawArea(area);
            }


            //Area2D(vv1, vv2, out float S11);
        }
        Debug.Log("Number of seen MPC1 = " + SeenV6_MPC1.Count);
        Debug.Log("Number of seen MPC2 = " + SeenV6_MPC2.Count);
        Debug.Log("Number of seen MPC3 = " + SeenV6_MPC3.Count);
    }
Пример #9
0
    public void Execute(int index)
    {
        if (MPC_array[index].Coordinates.x >= Xleft && MPC_array[index].Coordinates.x <= Xright && MPC_array[index].Coordinates.z >= Zdown && MPC_array[index].Coordinates.z <= Zup)
        {
            if (MPC_array[index].Inclusion == 0)
            {
                if (p1 == p2) // the polygon is a triangle
                {
                    Vector3 side1      = s1 - p1;
                    Vector3 side2      = s2 - p2;
                    float   S_triangle = Mathf.Abs(-side1.x * side2.z + side1.z * side2.x); // double area


                    // We check if MPC_array[index] is in the triangle side1 side2
                    Vector3 v1 = s1 - MPC_array[index].Coordinates;
                    Vector3 v2 = p1 - MPC_array[index].Coordinates;
                    Vector3 v3 = s2 - MPC_array[index].Coordinates;
                    float   S1 = Mathf.Abs(-v1.x * v2.z + v1.z * v2.x); // double area
                    float   S2 = Mathf.Abs(-v2.x * v3.z + v2.z * v3.x); // double area
                    float   S3 = Mathf.Abs(-v3.x * v1.z + v3.z * v1.x); // double area

                    if (Mathf.Abs(S_triangle - S1 - S2 - S3) < 0.001)
                    {
                        // if the sum of areas is almost equal to the whole area, then the MPC is included into the active set of MPCs
                        Vector3 new_norm = (n1 + n2).normalized;
                        MPC_V6[index]    = new V6(MPC_array[index].Coordinates, new_norm);
                        MPC_perp[index]  = new Vector3(-new_norm.z, 0, new_norm.x);
                        MPC_array[index] = new V4(MPC_array[index].Coordinates, 1);
                    }
                }
                else // the polygon is not a triangle
                {
                    float dot_prod_normals = Vector3.Dot(n1, n2);
                    if (dot_prod_normals <= 0)    // then the polygon is not convex (or triangle where p1 != p2)
                    {
                        // in this case, we consider two triangles separately
                        Vector3 v11 = p1 - s1;
                        Vector3 v12 = p2 - s1;
                        float   S1  = Mathf.Abs(-v11.x * v12.z + v11.z * v12.x); //(v11, v12, out float S1);

                        Vector3 v21 = p1 - s2;
                        Vector3 v22 = p2 - s2;
                        float   S2  = Mathf.Abs(-v21.x * v22.z + v21.z * v22.x); //Area2D(v21, v22, out float S2);
                                                                                 // we consider such strange triangles in order to cover the biggest area defined at leas with one correct triangle
                                                                                 // and at the same time to avoid considering a non-convex quadrangle

                        Vector3 vp1 = p1 - MPC_array[index].Coordinates;
                        Vector3 vp2 = p2 - MPC_array[index].Coordinates;

                        Vector3 vs1 = s1 - MPC_array[index].Coordinates;
                        Vector3 vs2 = s2 - MPC_array[index].Coordinates;

                        // common area that is related to both S1 and S2
                        float Spp = Mathf.Abs(-vp1.x * vp2.z + vp1.z * vp2.x); //Area2D(vp1, vp2, out float Spp);

                        // areas related to S1
                        float Sp1s1 = Mathf.Abs(-vp1.x * vs1.z + vp1.z * vs1.x); //Area2D(vp1, vs1, out float Sp1s1);
                        float Sp2s1 = Mathf.Abs(-vp2.x * vs1.z + vp2.z * vs1.x); //Area2D(vp2, vs1, out float Sp2s1);

                        // areas related to S2
                        float Sp1s2 = Mathf.Abs(-vp1.x * vs2.z + vp1.z * vs2.x); //Area2D(vp1, vs2, out float Sp1s2);
                        float Sp2s2 = Mathf.Abs(-vp2.x * vs2.z + vp2.z * vs2.x); //Area2D(vp2, vs2, out float Sp2s2);

                        // check if the point [i] belongs to S1 or S2
                        if (Mathf.Abs(S1 - Spp - Sp1s1 - Sp2s1) < 0.001)
                        {
                            MPC_V6[index]    = new V6(MPC_array[index].Coordinates, n1);
                            MPC_perp[index]  = new Vector3(-n1.z, 0, n1.x);
                            MPC_array[index] = new V4(MPC_array[index].Coordinates, 1);
                        }
                        else if (Mathf.Abs(S2 - Spp - Sp1s2 - Sp2s2) < 0.001)
                        {
                            MPC_V6[index]    = new V6(MPC_array[index].Coordinates, n2);
                            MPC_perp[index]  = new Vector3(-n2.z, 0, n2.x);
                            MPC_array[index] = new V4(MPC_array[index].Coordinates, 1);
                        }
                    }
                    else // the polygon is convex
                    {
                        // the first triangle of the quadrangle
                        Vector3 v11 = p1 - s1;
                        Vector3 v12 = s2 - s1;
                        float   S1  = Mathf.Abs(-v11.x * v12.z + v11.z * v12.x);//Area2D(v11, v12, out float S1);

                        // the second triangle of the quadrangle
                        Vector3 v21 = p1 - p2;
                        Vector3 v22 = s2 - p2;
                        float   S2  = Mathf.Abs(-v21.x * v22.z + v21.z * v22.x);//Area2D(v21, v22, out float S2);

                        Vector3 v1 = p1 - MPC_array[index].Coordinates;
                        Vector3 v2 = s1 - MPC_array[index].Coordinates;
                        Vector3 v3 = s2 - MPC_array[index].Coordinates;
                        Vector3 v4 = p2 - MPC_array[index].Coordinates;

                        float A1 = Mathf.Abs(-v1.x * v2.z + v1.z * v2.x); //Area2D(v1, v2, out float A1);
                        float A2 = Mathf.Abs(-v2.x * v3.z + v2.z * v3.x); //Area2D(v2, v3, out float A2);
                        float A3 = Mathf.Abs(-v3.x * v4.z + v3.z * v4.x); //Area2D(v3, v4, out float A3);
                        float A4 = Mathf.Abs(-v4.x * v1.z + v4.z * v1.x); //Area2D(v4, v1, out float A4);


                        float area_diff = Mathf.Abs(S1 + S2 - A1 - A2 - A3 - A4);

                        if (area_diff < 1)
                        {
                            Vector3 new_norm = (n1 + n2).normalized;
                            MPC_V6[index]    = new V6(MPC_array[index].Coordinates, new_norm);
                            MPC_perp[index]  = new Vector3(-new_norm.z, 0, new_norm.x);
                            MPC_array[index] = new V4(MPC_array[index].Coordinates, 1);
                        }
                    }
                }
            }
        }
    }
Пример #10
0
    /*
    // Update is called once per frame
    void Update()
    {
        update_flag = 1;

        Rx_MPC1 = Rx_Seen_MPC_Script.seen_MPC1;
        Rx_MPC2 = Rx_Seen_MPC_Script.seen_MPC2;
        Rx_MPC3 = Rx_Seen_MPC_Script.seen_MPC3;

        Tx_MPC1 = Tx_Seen_MPC_Script.seen_MPC1;
        Tx_MPC2 = Tx_Seen_MPC_Script.seen_MPC2;
        Tx_MPC3 = Tx_Seen_MPC_Script.seen_MPC3;


    }
    */

    private void FixedUpdate()
    {
        Rx_MPC1 = Rx_Seen_MPC_Script.seen_MPC1;
        Rx_MPC2 = Rx_Seen_MPC_Script.seen_MPC2;
        Rx_MPC3 = Rx_Seen_MPC_Script.seen_MPC3;

        Tx_MPC1 = Tx_Seen_MPC_Script.seen_MPC1;
        Tx_MPC2 = Tx_Seen_MPC_Script.seen_MPC2;
        Tx_MPC3 = Tx_Seen_MPC_Script.seen_MPC3;



        ///////////////////////////////////////////////////////////////////////////////////
        /// LOS
        ///////////////////////////////////////////////////////////////////////////////////
        // float startTime = Time.realtimeSinceStartup;
        if (!Physics.Linecast(Tx.transform.position, Rx.transform.position))
        {
            float LOS_distance = (Tx.transform.position - Rx.transform.position).magnitude;
            if (LOS_Tracer)
            {
                Debug.DrawLine(Tx.transform.position, Rx.transform.position, Color.magenta);
            }
        }
        // Debug.Log(((Time.realtimeSinceStartup - startTime) * 1000000f) + "microsec");
        ///////////////////////////////////////////////////////////////////////////////////
        /// MPC1
        ///////////////////////////////////////////////////////////////////////////////////
        List<int> common_mpc1 = new List<int>();

        CommonMPC1(Rx_MPC1, Tx_MPC1, out common_mpc1);

        List<int> active_MPC1 = new List<int>();
        for (int i = 0; i < common_mpc1.Count; i++)

        {
            // defining peprendicular to the considered normal that is parallel to the ground. 
            Vector3 n_perp = new Vector3(-MPC1[common_mpc1[i]].Normal.z, 0, MPC1[common_mpc1[i]].Normal.x);
            float rx_distance = (Rx.transform.position - MPC1[common_mpc1[i]].Coordinates).magnitude;
            float tx_distance = (Rx.transform.position - MPC1[common_mpc1[i]].Coordinates).magnitude;
            Vector3 rx_direction = (Rx.transform.position - MPC1[common_mpc1[i]].Coordinates).normalized;
            Vector3 tx_direction = (Tx.transform.position - MPC1[common_mpc1[i]].Coordinates).normalized;

            if ((Vector3.Dot(n_perp, rx_direction) * Vector3.Dot(n_perp, tx_direction)) < 0)
            {
                active_MPC1.Add(common_mpc1[i]);
                if (MPC1_Tracer)
                {
                    Debug.DrawLine(Rx.transform.position, MPC1[common_mpc1[i]].Coordinates, Color.red);
                    Debug.DrawLine(Tx.transform.position, MPC1[common_mpc1[i]].Coordinates, Color.blue);
                }
            }
        }




        ///////////////////////////////////////////////////////////////////////////////////
        /// MPC2
        ///////////////////////////////////////////////////////////////////////////////////
        List<Path2> second_order_paths = new List<Path2>();

        int brute_force = 1;
        for (int i = 0; i < Rx_MPC2.Count; i++)
        {
            List<GeoComp> temp_list = new List<GeoComp>();
            if (brute_force == 1)
            {
                temp_list = GlobeCom2[Rx_MPC2[i]];
            }
            else
            {
                for (int j = 0; j < MPC2.Count; j++)
                {
                    float dist_xxx = (MPC2[j].Coordinates - MPC2[Rx_MPC2[i]].Coordinates).magnitude;
                    if (dist_xxx < 70)
                    {
                        if (!Physics.Linecast(MPC2[j].Coordinates, MPC2[Rx_MPC2[i]].Coordinates))
                        {
                            float aod = Mathf.Acos(Vector3.Dot((MPC2[j].Coordinates - MPC2[Rx_MPC2[i]].Coordinates).normalized, MPC2[j].Normal));
                            float aoa = Mathf.Acos(-Vector3.Dot((MPC2[j].Coordinates - MPC2[Rx_MPC2[i]].Coordinates).normalized, MPC2[Rx_MPC2[i]].Normal));
                            GeoComp asd = new GeoComp(j, dist_xxx, aod, aoa);
                            temp_list.Add(asd);
                        }
                    }
                }
            }

            for (int ii = 0; ii < Tx_MPC2.Count; ii++)
            {
                if (temp_list.Any(geocom => geocom.MPCIndex == Tx_MPC2[ii]))
                {
                    int temp_index = temp_list.FindIndex(geocom => geocom.MPCIndex == Tx_MPC2[ii]);
                    // defining peprendicular to the considered normal that is parallel to the ground. 
                    V6 temp_Rx_MPC2 = MPC2[Rx_MPC2[i]];
                    V6 temp_Tx_MPC2 = MPC2[Tx_MPC2[ii]];

                    Vector3 n_perp1 = new Vector3(-temp_Rx_MPC2.Normal.z, 0, temp_Rx_MPC2.Normal.x);
                    Vector3 Rx_dir1 = (Rx.transform.position - temp_Rx_MPC2.Coordinates).normalized;
                    Vector3 RT = (temp_Tx_MPC2.Coordinates - temp_Rx_MPC2.Coordinates).normalized;

                    Vector3 n_perp2 = new Vector3(-temp_Tx_MPC2.Normal.z, 0, temp_Tx_MPC2.Normal.x);
                    Vector3 Tx_dir2 = (Tx.transform.position - temp_Tx_MPC2.Coordinates).normalized;
                    Vector3 TR = (temp_Rx_MPC2.Coordinates - temp_Tx_MPC2.Coordinates).normalized;

                    if ((Vector3.Dot(n_perp1, Rx_dir1) * Vector3.Dot(n_perp1, RT) < 0) && (Vector3.Dot(n_perp2, Tx_dir2) * Vector3.Dot(n_perp2, TR) < 0))
                    {
                        float rx_distance2MPC2 = (Rx.transform.position - MPC2[Rx_MPC2[i]].Coordinates).magnitude;
                        float tx_distance2MPC2 = (Tx.transform.position - MPC2[Tx_MPC2[ii]].Coordinates).magnitude;
                        float MPC2_distance = temp_list[temp_index].Distance;
                        float total_distance = rx_distance2MPC2 + MPC2_distance + tx_distance2MPC2;

                        Path2 temp_path2 = new Path2(Rx.transform.position, MPC2[Rx_MPC2[i]].Coordinates, MPC2[Tx_MPC2[ii]].Coordinates, Tx.transform.position, total_distance, 0.0f);
                        second_order_paths.Add(temp_path2);
                        if (MPC2_Tracer)
                        {
                            Debug.DrawLine(temp_path2.Rx_Point, temp_path2.MPC2_1, Color.green);
                            Debug.DrawLine(temp_path2.MPC2_1, temp_path2.MPC2_2, Color.yellow);
                            Debug.DrawLine(temp_path2.MPC2_2, temp_path2.Tx_Point, Color.cyan);
                        }
                    }
                }
            }

        }



    }
Пример #11
0
    // Start is called before the first frame update
    void Start()
    {
        // Declaring buildings and observation points
        Buildings = GameObject.FindGameObjectsWithTag("Reflecting_Obstacles");
        // The number of observation points should not be too big, a few is enough
        Observation_Points = GameObject.FindGameObjectsWithTag("Observation_Points");
        // Define the main road direction
        Vector3 main_axis = (Observation_Points[0].transform.position - Observation_Points[1].transform.position).normalized;
        Vector3 perp_axis = new Vector3(main_axis.z, 0, -main_axis.x);

        // subset of the seen Buldings
        List <GameObject> Building_list = new List <GameObject>();

        // Going through all observation points
        for (int k = 0; k < Observation_Points.Length; k++)
        {
            // analyzing which buidings are seen
            for (int b = 0; b < Buildings.Length; b++)
            {
                Vector3[] vrtx = Buildings[b].GetComponent <MeshFilter>().mesh.vertices;
                Vector3[] nrml = Buildings[b].GetComponent <MeshFilter>().mesh.normals;

                int seen_vrtx_count = 0;

                for (int v = 0; v < vrtx.Length; v++)
                {
                    if (vrtx[v].y == 0)
                    {
                        if (!Physics.Linecast(Observation_Points[k].transform.position, vrtx[v] + 1.1f * nrml[v]))
                        {
                            seen_vrtx_count += 1;
                        }
                    }
                }
                if (seen_vrtx_count != 0)
                {
                    if (!Building_list.Contains(Buildings[b]))
                    {
                        Building_list.Add(Buildings[b]);
                    }
                }
            }
        }

        // deactivating nonseen buildings
        for (int b = 0; b < Buildings.Length; b++)
        {
            if (!Building_list.Contains(Buildings[b]))
            {
                Buildings[b].SetActive(false);
            }
        }
        Debug.Log("The number of seen Buildings = " + Building_list.Count);


        // analyzing each seen building separately
        for (int k = 0; k < Building_list.Count; k++)
        {
            // writing MPCs into a txt file
            string        writePath;
            List <string> Obj_List = new List <string>();

            Vector3[] vrtx = Building_list[k].GetComponent <MeshFilter>().mesh.vertices;
            Vector3[] nrml = Building_list[k].GetComponent <MeshFilter>().mesh.normals;

            List <Vector3> floor_vrtx = new List <Vector3>();
            List <Vector3> floor_nrml = new List <Vector3>();
            var            pairs      = new List <V6>();

            List <Vector3> possible_vrtx = new List <Vector3>();
            List <Vector3> possible_nrml = new List <Vector3>();



            for (int l = 0; l < vrtx.Length; l++)
            {
                if (vrtx[l].y == 0 && Mathf.Abs(nrml[l].y) < 0.9)
                {
                    floor_vrtx.Add(vrtx[l]);
                    floor_nrml.Add(nrml[l]);

                    // adding coordinates and normals of the vertices into a single object V6 (like a N x 6 matrix)
                    V6 valid_pair = new V6(vrtx[l], nrml[l]);
                    pairs.Add(valid_pair);
                }
            }

            List <Vector3> floor_points = Remove_repetiting_points(floor_vrtx);

            Vector3 cg = new Vector3(0.0f, 0.0f, 0.0f);

            for (int l = 0; l < floor_points.Count; l++)
            {
                cg = cg + floor_points[l];

                /*
                 * GameObject cleared_sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                 *
                 * cleared_sphere.transform.position = floor_points[l];
                 * Destroy(cleared_sphere.GetComponent<SphereCollider>()); // remove collider
                 * var sphereRenderer = cleared_sphere.GetComponent<Renderer>();
                 * sphereRenderer.material = ObsPoint_Material;
                 * cleared_sphere.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
                 */
            }
            cg /= floor_points.Count;


            // update cg that takes into account the closest verteces
            Search_for_weighted_CG(floor_points, cg, 1.0f, out Vector3 updated_cg);


            GameObject upc_sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            upc_sphere.transform.position = updated_cg;
            Destroy(upc_sphere.GetComponent <SphereCollider>()); // remove collider
            var upc_sphereRenderer = upc_sphere.GetComponent <Renderer>();
            upc_sphereRenderer.material = CG_Material;

            // search for max distance
            float max_dist = 0;
            for (int l = 0; l < floor_points.Count; l++)
            {
                float temp_dist = (floor_points[l] - updated_cg).magnitude;
                if (temp_dist > max_dist)
                {
                    max_dist = temp_dist;
                }
            }

            // defining four observation points around a building that are on the car's antenna height
            Vector3   height_of_car             = new Vector3(0.0f, 1.3f, 0.0f);
            Vector3[] check_points              = new Vector3[4];
            float     how_much_step_out_from_cg = 2;
            check_points[0] = updated_cg + main_axis * (max_dist * how_much_step_out_from_cg) + height_of_car;
            check_points[1] = updated_cg + perp_axis * (max_dist * how_much_step_out_from_cg) + height_of_car;
            check_points[2] = updated_cg - main_axis * (max_dist * how_much_step_out_from_cg) + height_of_car;
            check_points[3] = updated_cg - perp_axis * (max_dist * how_much_step_out_from_cg) + height_of_car;

            // We create 8 observation points that are located outside of the building and are surrounding it
            // All the seen vertices of a floor, we save into a List < List < V4 > > structure
            List <List <V4> > seen_points = new List <List <V4> >();
            int check_point = 3;
            for (int l = 0; l < 8; l++)
            {
                Vector3 obs_point = new Vector3(0, 0, 0);
                if (l % 2 == 0)
                {
                    obs_point = check_points[l / 2];
                }
                else
                { // if l is odd, we take half of the sum of two neighboring points
                    if (l != 7)
                    {
                        obs_point = (check_points[(l - 1) / 2] + check_points[(l + 1) / 2]) / 2;
                    }
                    else
                    {
                        obs_point = (check_points[3] + check_points[0]) / 2;
                    }
                }
                Vector3 obs2cg    = (updated_cg - obs_point).normalized;
                Vector3 obs2right = -Vector3.Cross(obs2cg, new Vector3(0, 1, 0));
                if (l == check_point)
                {
                    Debug.DrawLine(obs_point, obs_point + obs2cg * 3.0f, Color.green, 5.0f);
                    Debug.DrawLine(obs_point, obs_point + obs2right * 3.0f, Color.red, 5.0f);
                }

                // defining list of seen point for each observation point
                List <V4> side_seen_points = new List <V4>();
                for (int n = 0; n < floor_points.Count; n++)
                {
                    // defining direction and distance from the observation point to floor points
                    Vector3 temp_dir  = (floor_points[n] - obs_point);
                    float   temp_dist = temp_dir.magnitude;
                    Vector3 unit_dir  = temp_dir.normalized;

                    if (Physics.Raycast(obs_point, unit_dir, out RaycastHit hitInfo, temp_dist - 0.01f))
                    {
                        //Debug.Log("Hit something");
                    }
Пример #12
0
    // Start is called before the first frame update
    void Start()
    {
        // Declaring buildings and observation points
        Buildings          = GameObject.FindGameObjectsWithTag("Reflecting_Obstacles");
        Observation_Points = GameObject.FindGameObjectsWithTag("Observation_Points");
        // subset of the seen Buldings
        List <GameObject> Building_list = new List <GameObject>();

        // Going through all observation points
        for (int k = 0; k < Observation_Points.Length; k++)
        {
            // analyzing which buidings are seen
            for (int b = 0; b < Buildings.Length; b++)
            {
                Vector3[] vrtx = Buildings[b].GetComponent <MeshFilter>().mesh.vertices;
                Vector3[] nrml = Buildings[b].GetComponent <MeshFilter>().mesh.normals;

                int seen_vrtx_count = 0;

                for (int v = 0; v < vrtx.Length; v++)
                {
                    if (vrtx[v].y == 0)
                    {
                        if (!Physics.Linecast(Observation_Points[k].transform.position, vrtx[v] + 1.1f * nrml[v]))
                        {
                            seen_vrtx_count += 1;
                        }
                    }
                }
                if (seen_vrtx_count != 0)
                {
                    if (!Building_list.Contains(Buildings[b]))
                    {
                        Building_list.Add(Buildings[b]);
                    }
                }
            }
        }

        // deactivating nonseen buildings
        for (int b = 0; b < Buildings.Length; b++)
        {
            if (!Building_list.Contains(Buildings[b]))
            {
                Buildings[b].SetActive(false);
            }
        }
        Debug.Log("The number of seen Buildings = " + Building_list.Count);

        int checked_k = 10000;

        // analyzing each seen building separately
        for (int k = 0; k < Building_list.Count; k++)
        {
            Vector3[] vrtx = Building_list[k].GetComponent <MeshFilter>().mesh.vertices;
            Vector3[] nrml = Building_list[k].GetComponent <MeshFilter>().mesh.normals;

            List <Vector3> floor_vrtx = new List <Vector3>();
            List <Vector3> floor_nrml = new List <Vector3>();
            var            pairs      = new List <V6>();

            List <Vector3> possible_vrtx = new List <Vector3>();
            List <Vector3> possible_nrml = new List <Vector3>();


            for (int l = 0; l < vrtx.Length; l++)
            {
                if (vrtx[l].y == 0 && Mathf.Abs(nrml[l].y) < 0.9)
                {
                    floor_vrtx.Add(vrtx[l]);
                    floor_nrml.Add(nrml[l]);

                    GameObject v_sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);

                    v_sphere.transform.position = vrtx[l];
                    Destroy(v_sphere.GetComponent <SphereCollider>()); // remove collider
                    var sphereRenderer = v_sphere.GetComponent <Renderer>();
                    sphereRenderer.material = ObsPoint_Material;

                    // adding coordinates and normals of the vertices into a single object V6 (like a N x 6 matrix)
                    V6 valid_pair = new V6(vrtx[l], nrml[l]);
                    pairs.Add(valid_pair);
                }
            }


            // lb_start - the left bottom vertex with
            Search_for_LeftBottom(pairs, out V6 lb_start, out V6 lb_end);


            //GameObject v_sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);

            //v_sphere.transform.position = lb_start.Coordinates;
            //Destroy(v_sphere.GetComponent<SphereCollider>()); // remove collider
            Debug.DrawLine(lb_start.Coordinates, lb_start.Coordinates + 3.0f * lb_start.Normal, Color.green, 5.0f);
            //v_sphere.transform.position = lb_end.Coordinates;
            //Destroy(v_sphere.GetComponent<SphereCollider>()); // remove collider
            Debug.DrawLine(lb_end.Coordinates, lb_end.Coordinates + 3.0f * lb_end.Normal, Color.blue, 5.0f);
            //var sphereRenderer = v_sphere.GetComponent<Renderer>();
            //sphereRenderer.material = ObsPoint_Material;



            // TODO: the method is assuming that all Normals have zero Y components (it may not work for an arbitrary Normal with nonzero Normal.y)
            List <V6> remaining_pairs = pairs;
            List <V6> close_loop_poly = new List <V6>();

            float steps_out = 2.0f;

            // remove the elements step by step from the list of vrtx and nrml
            V6 next_V6_to_remove = lb_start;
            close_loop_poly.Add(next_V6_to_remove);         // adding to the close loop list
            remaining_pairs.Remove(next_V6_to_remove);      // removing from the consideration
            int if_loop_is_closed            = 0;           // flag indicating the end of the loop
            int to_avoid_the_first_step_stop = 0;
            // remove elements until we consider all the elements of the outer side
            while (remaining_pairs.Count > 0 && if_loop_is_closed != 1)
            {
                // define perpendicular direction to the given Normal of next_V6_to_remove (it may not work for an arbitrary Normal with nonzero Normal.y)
                Vector3 temp_perpendicular = new Vector3(next_V6_to_remove.Normal.z, 0, -next_V6_to_remove.Normal.x).normalized; // a vector product in 3D with (0, 1, 0)

                // several vertexes can lay in the direction of temp_perpendicular
                List <V6> possible_pairs        = new List <V6>();
                List <V2> distance_index        = new List <V2>(); // to track distances and indexes
                List <V3> distence_index_ncount = new List <V3>(); // to track distances, indexes, and number of normals


                int possibilities_count = 0;
                int check_count1        = 0;
                for (int j = 0; j < remaining_pairs.Count; j++)
                {
                    //if (j == 0 && possibilities_count == 0)
                    //{
                    //Debug.DrawLine(next_V6_to_remove.Coordinates + 1.0f * next_V6_to_remove.Normal, remaining_pairs[j].Coordinates, Color.yellow, 5.0f);
                    //}
                    if ((next_V6_to_remove.Normal - remaining_pairs[j].Normal).magnitude < 0.05)
                    {
                        Vector3 temp_direction = remaining_pairs[j].Coordinates - next_V6_to_remove.Coordinates;
                        if ((temp_direction.normalized - temp_perpendicular).magnitude < 0.037) // in order to take into account numerical errors
                        {
                            Vector3 A2B = remaining_pairs[j].Coordinates - (next_V6_to_remove.Coordinates + steps_out * next_V6_to_remove.Normal);
                            if (Physics.Raycast(next_V6_to_remove.Coordinates + steps_out * next_V6_to_remove.Normal, A2B.normalized, out RaycastHit hitInfo, (A2B.magnitude - 0.01f)))
                            {
                                if (Building_list[k].name == "Building256" && remaining_pairs.Count == 4)
                                {
                                    //Debug.Log("hit Info " + hitInfo);
                                    Debug.DrawLine(next_V6_to_remove.Coordinates + steps_out * next_V6_to_remove.Normal, next_V6_to_remove.Coordinates + steps_out * next_V6_to_remove.Normal + A2B.normalized * (A2B.magnitude - 0.01f), Color.cyan, Mathf.Infinity);
                                }
                            }
                            else
                            {
                                //if (Building_list[k].name == "Building284" && remaining_pairs.Count == 13)
                                {
                                    //Debug.DrawLine(next_V6_to_remove.Coordinates + 1.0f * next_V6_to_remove.Normal, next_V6_to_remove.Coordinates + 1.0f * next_V6_to_remove.Normal + A2B.normalized * (A2B.magnitude - 0.01f), Color.cyan, 5.0f);
                                }

                                possible_pairs.Add(remaining_pairs[j]);

                                int nCount = 1;
                                // searching if there are vertices with the same coordinates but different normals
                                for (int jj = 0; jj < remaining_pairs.Count; jj++)
                                {
                                    if (remaining_pairs[j].Coordinates == remaining_pairs[jj].Coordinates && j != jj)
                                    {
                                        nCount += 1;
                                    }
                                }

                                if (nCount > 2)
                                {
                                    Debug.Log("Something wrong: a vertex has more than two normals");
                                }
                                if (nCount == 2)
                                {
                                    check_count1 += 1;
                                }

                                V3 dIDnCount = new V3(temp_direction.magnitude, possibilities_count, nCount);
                                distence_index_ncount.Add(dIDnCount);

                                possibilities_count += 1;
                            }
                        }
                    }
                }

                //Debug.Log("How many vertices on the same side of building #" + Building_list[k].name + " have left " + distence_index_ncount.Count);


                if (distence_index_ncount.Count == 0)
                {
                    Debug.Log("Check here! Buildign name " + Building_list[k].name);
                }


                List <V3> SortedByDistance = distence_index_ncount.OrderBy(d => d.Distance).ToList();

                if (k == 50)
                {
                    Debug.Log("Check!");
                }

                int srch_steps = 0;
                while (SortedByDistance[srch_steps].Normals_Number < 2 && if_loop_is_closed != 1)
                {
                    if (checked_k != k)
                    {
                        Debug.Log("Drawing lines for building #" + k);
                        checked_k = k;
                    }
                    // removing all the vertecies that
                    Debug.DrawLine(next_V6_to_remove.Coordinates, possible_pairs[SortedByDistance[srch_steps].Index].Coordinates, Color.red, 5.0f);
                    next_V6_to_remove = possible_pairs[SortedByDistance[srch_steps].Index];
                    close_loop_poly.Add(next_V6_to_remove);
                    remaining_pairs.Remove(next_V6_to_remove);
                    srch_steps += 1;
                    if (next_V6_to_remove.Coordinates == lb_end.Coordinates) // check if the last vertex does not match with the last vertex of the loop
                    {
                        if_loop_is_closed = 1;
                        srch_steps       -= 1;
                    }
                }

                if (k == 12)
                {
                    Debug.Log("Check ");
                }

                if (SortedByDistance[srch_steps].Normals_Number > 1)
                {
                    if (checked_k != k)
                    {
                        Debug.Log("Drawing lines for building #" + k);
                        checked_k = k;
                    }
                    Debug.DrawLine(next_V6_to_remove.Coordinates, possible_pairs[SortedByDistance[srch_steps].Index].Coordinates, Color.red, 5.0f);
                    next_V6_to_remove = possible_pairs[SortedByDistance[srch_steps].Index];
                    close_loop_poly.Add(next_V6_to_remove);
                    remaining_pairs.Remove(next_V6_to_remove);

                    int matching_number = 0;
                    for (int iii = 0; iii < remaining_pairs.Count; iii++)
                    {
                        if (next_V6_to_remove.Coordinates == remaining_pairs[iii].Coordinates)
                        {
                            next_V6_to_remove = remaining_pairs[iii];
                            matching_number  += 1;

                            close_loop_poly.Add(next_V6_to_remove);
                            remaining_pairs.Remove(next_V6_to_remove);
                        }
                    }
                }


                to_avoid_the_first_step_stop += 1;
            }

            //Debug.Log("Number of Vertices of the building = " + pairs.Count);
            //Debug.Log("Number of Vertices of the building after closing the loop = " + close_loop_poly.Count);
        }
    // Start is called before the first frame update
    void Start()
    {
        // Declaring buildings and observation points
        Buildings = GameObject.FindGameObjectsWithTag("Reflecting_Obstacles");
        // The number of observation points should not be too big, a few is enough
        Observation_Points = GameObject.FindGameObjectsWithTag("Observation_Points");
        // Define the main road direction
        Vector3 main_axis = (Observation_Points[0].transform.position - Observation_Points[1].transform.position).normalized;
        Vector3 perp_axis = new Vector3(main_axis.z, 0, -main_axis.x);

        // subset of the seen Buldings
        List <GameObject> Building_list = new List <GameObject>();

        // Going through all observation points
        for (int k = 0; k < Observation_Points.Length; k++)
        {
            // analyzing which buidings are seen
            for (int b = 0; b < Buildings.Length; b++)
            {
                Vector3[] vrtx = Buildings[b].GetComponent <MeshFilter>().mesh.vertices;
                Vector3[] nrml = Buildings[b].GetComponent <MeshFilter>().mesh.normals;

                int seen_vrtx_count = 0;

                for (int v = 0; v < vrtx.Length; v++)
                {
                    if (vrtx[v].y == 0)
                    {
                        if (!Physics.Linecast(Observation_Points[k].transform.position, vrtx[v] + 1.1f * nrml[v]))
                        {
                            seen_vrtx_count += 1;
                        }
                    }
                }
                if (seen_vrtx_count != 0)
                {
                    if (!Building_list.Contains(Buildings[b]))
                    {
                        Building_list.Add(Buildings[b]);
                    }
                }
            }
        }

        // deactivating nonseen buildings
        for (int b = 0; b < Buildings.Length; b++)
        {
            if (!Building_list.Contains(Buildings[b]))
            {
                Buildings[b].SetActive(false);
            }
        }
        Debug.Log("The number of seen Buildings = " + Building_list.Count);


        // analyzing each seen building separately
        for (int k = 0; k < Building_list.Count; k++)
        {
            // writing MPCs into a txt file
            //string writePath;
            List <string> Obj_List = new List <string>();

            Vector3[] vrtx = Building_list[k].GetComponent <MeshFilter>().mesh.vertices;
            Vector3[] nrml = Building_list[k].GetComponent <MeshFilter>().mesh.normals;

            List <Vector3> floor_vrtx = new List <Vector3>();
            List <Vector3> floor_nrml = new List <Vector3>();
            var            pairs      = new List <V6>();

            List <Vector3> possible_vrtx = new List <Vector3>();
            List <Vector3> possible_nrml = new List <Vector3>();



            for (int l = 0; l < vrtx.Length; l++)
            {
                if (vrtx[l].y == 0 && Mathf.Abs(nrml[l].y) < 0.9)
                {
                    floor_vrtx.Add(vrtx[l]);
                    floor_nrml.Add(nrml[l]);

                    // adding coordinates and normals of the vertices into a single object V6 (like a N x 6 matrix)
                    V6 valid_pair = new V6(vrtx[l], nrml[l]);
                    pairs.Add(valid_pair);
                }
            }

            for (int l = 0; l < floor_vrtx.Count - 1; l++)
            {
                Debug.DrawLine(floor_vrtx[l], floor_vrtx[l + 1], Color.cyan, 5.0f);
            }


            List <Vector3> floor_points = Remove_repetiting_points(floor_vrtx);

            Vector3 cg = new Vector3(0.0f, 0.0f, 0.0f);

            for (int l = 0; l < floor_points.Count; l++)
            {
                cg = cg + floor_points[l];

                /*
                 * GameObject cleared_sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                 *
                 * cleared_sphere.transform.position = floor_points[l];
                 * Destroy(cleared_sphere.GetComponent<SphereCollider>()); // remove collider
                 * var sphereRenderer = cleared_sphere.GetComponent<Renderer>();
                 * sphereRenderer.material = ObsPoint_Material;
                 * cleared_sphere.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
                 */
            }
            cg /= floor_points.Count;


            // update cg that takes into account the closest verteces
            Search_for_weighted_CG(floor_points, cg, 1.0f, out Vector3 updated_cg);

            /*
             * GameObject upc_sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
             * upc_sphere.transform.position = updated_cg;
             * Destroy(upc_sphere.GetComponent<SphereCollider>()); // remove collider
             * var upc_sphereRenderer = upc_sphere.GetComponent<Renderer>();
             * upc_sphereRenderer.material = CG_Material;
             *
             * // search for max distance
             * float max_dist = 0;
             * for (int l = 0; l < floor_points.Count; l++)
             * {
             *  float temp_dist = (floor_points[l] - updated_cg).magnitude;
             *  if (temp_dist > max_dist) { max_dist = temp_dist; }
             * }
             *
             * // defining four observation points around a building that are on the car's antenna height
             * Vector3 height_of_car = new Vector3(0.0f, 1.3f, 0.0f);
             * Vector3[] check_points = new Vector3[4];
             * float how_much_step_out_from_cg = 3.0f;
             * check_points[0] = updated_cg + main_axis * (max_dist * how_much_step_out_from_cg) + height_of_car;
             * check_points[1] = updated_cg + perp_axis * (max_dist * how_much_step_out_from_cg) + height_of_car;
             * check_points[2] = updated_cg - main_axis * (max_dist * how_much_step_out_from_cg) + height_of_car;
             * check_points[3] = updated_cg - perp_axis * (max_dist * how_much_step_out_from_cg) + height_of_car;
             *
             * // We create 8 observation points that are located outside of the building and are surrounding it
             * // All the seen vertices of a floor, we save into a List < List < V4 > > structure
             * List<List<V4>> seen_points = new List<List<V4>>();
             *
             * // Choos the check point, for which verteces are highlighted
             * int check_point = 4;
             * for (int l = 0; l < 8; l++)
             * {
             *
             *  Vector3 obs_point = new Vector3(0,0,0);
             *  if (l % 2 == 0) { obs_point = check_points[l / 2];}
             *  else
             *  { // if l is odd, we take half of the sum of two neighboring points
             *      if (l != 7){ obs_point = (check_points[(l - 1) / 2] + check_points[(l + 1) / 2])/2; }
             *      else { obs_point = (check_points[3] + check_points[0])/2; }
             *  }
             *  Vector3 obs2cg = (updated_cg - obs_point).normalized;
             *  Vector3 obs2right = -Vector3.Cross(obs2cg, new Vector3(0, 1, 0));
             *  if (l == check_point)
             *  {
             *      Debug.DrawLine(obs_point, obs_point + obs2cg * 3.0f, Color.green, 5.0f);
             *      Debug.DrawLine(obs_point, obs_point + obs2right * 3.0f, Color.red, 5.0f);
             *  }
             *
             *  // defining list of seen point for each observation point
             *  List<V4> side_seen_points = new List<V4>();
             *  for (int n = 0; n < floor_points.Count; n++)
             *  {
             *      // defining direction and distance from the observation point to floor points
             *      Vector3 temp_dir = (floor_points[n] - obs_point);
             *      float temp_dist = temp_dir.magnitude;
             *      Vector3 unit_dir = temp_dir.normalized;
             *
             *      if( Physics.Raycast(obs_point, unit_dir, out RaycastHit hitInfo, temp_dist - 0.01f) )
             *      {
             *          //Debug.Log("Hit something");
             *      }
             *      else
             *      {
             *          float temp_cos = 1.0f - Vector3.Dot(unit_dir, obs2right); // 1 - cos(phi) from 0 to 2
             *          V4 point_angle = new V4(floor_points[n], temp_cos);
             *          side_seen_points.Add(point_angle);
             *
             *
             *          if (l == check_point)
             *          {
             *              GameObject cleared_sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
             *
             *              cleared_sphere.transform.position = floor_points[n];
             *              Destroy(cleared_sphere.GetComponent<SphereCollider>()); // remove collider
             *              var sphereRenderer = cleared_sphere.GetComponent<Renderer>();
             *              sphereRenderer.material = ObsPoint_Material;
             *              cleared_sphere.transform.localScale = new Vector3(1.1f, 1.1f, 1.1f);
             *          }
             *
             *      }
             *
             *  }
             *  var SortedByCos = side_seen_points.OrderBy(xx => xx.Distance).ToList();
             *  seen_points.Add(SortedByCos);
             *  //for (int m = 0; m < SortedByCos.Count; m++)
             *  //{
             *  //    Obj_List.Add("Obs point #" + l + "," + SortedByCos[m].Coordinates.x + "," + SortedByCos[m].Coordinates.z + "," + SortedByCos[m].Distance);
             *  //}
             *
             * }
             * // defining the text file and writing
             * // writePath = Application.dataPath + "/obs2_point" + ".csv";
             * // WriteFile(Obj_List, writePath);
             *
             * // Check the very first list and the very last list since they are overlaping with each other
             * // This is done to avoid unseen verteces from the first observation point (Exampl: Berlin, building 302)
             * int temp_entrance_pos = 0;
             * for (int l = 0; l < seen_points[0].Count; l++)
             * {
             *  int current_pos = 0;
             *  int flag = 0;
             *  while(flag == 0 && temp_entrance_pos + current_pos < seen_points[7].Count)
             *  {
             *      if (seen_points[0][l].Coordinates == seen_points[7][temp_entrance_pos + current_pos].Coordinates)
             *      {
             *          flag = 1;
             *          temp_entrance_pos = temp_entrance_pos + current_pos + 1;
             *          if (l > 0 && current_pos > 0)
             *          {
             *              seen_points[0].Remove(seen_points[0][l-1]);
             *              l -= 1;
             *          }
             *      }
             *      else { current_pos += 1; }
             *  }
             * }
             *
             * List<V4> previous_list = seen_points[0];
             * for (int n = 1; n < seen_points.Count; n++)
             * //for (int n = 3; n < 4; n++)
             * {
             *  // ASSUMPTION1: the first vertex from the next set is always existing in the previous set
             *  // ASSUMPTION2: the last vertex from the previous set is always existing in the next set
             *  // TODO: this can be formulated as a theorem and proven
             *
             *  // According to the assumption, we search for the first vertex location in the previous set
             *  List<int> coincidence_positions_prev = new List<int>();
             *  List<int> coincidence_positions_next = new List<int>();
             *
             *  // it is very crucial to find the first entrance that is located as far as possible (in terms of sequence position)
             *  int first_entrance_pos = 0;
             *  for (int i = 0; i < previous_list.Count; i++)
             *  {
             *      if (previous_list[i].Coordinates == seen_points[n][0].Coordinates)
             *      { first_entrance_pos = i; }
             *  }
             *  coincidence_positions_prev.Add(first_entrance_pos);
             *  coincidence_positions_next.Add(0);
             *
             *  // this wierd step is done in order to separate all previous positions from the first entrance
             *  // TODO: this needs to be checked
             *  int previous_entrance_pos = first_entrance_pos;
             *  int entrance_num = 1;
             *  for (int nn = 1; nn < seen_points[n].Count; nn++)
             *  {
             *
             *      int entrance_flag = 0;
             *      int entrance_pos = 1;
             *      while (entrance_flag == 0 && previous_entrance_pos + entrance_pos < previous_list.Count)
             *      {
             *          if (previous_list[previous_entrance_pos + entrance_pos].Coordinates == seen_points[n][nn].Coordinates)
             *          {
             *              entrance_flag = 1;
             *              previous_entrance_pos = previous_entrance_pos + entrance_pos;
             *              // adding indexes to the set of entrance indexes
             *              coincidence_positions_prev.Add(previous_entrance_pos);
             *              coincidence_positions_next.Add(nn);
             *              Debug.Log("Vertex " + nn + " is found in the previous list on position " + previous_entrance_pos);
             *
             *
             *              entrance_num += 1;
             *          }
             *
             *          entrance_pos += 1;
             *      }
             *  }
             *
             *  // defining sets: previous set is referred as prev[]; next set is referred as next[].
             *  // Assumption: in the final vertexes sequence, prev[0] >= next[0] and prev[end] >= next[end]
             *  // here ">=" mean higher or on the same place in terms of sequence position
             *  List<V4> temp_list = new List<V4>();
             *  // add everything from previous_list before the first entrance
             *  for (int nnn = 0; nnn < coincidence_positions_prev[0]; nnn++)
             *  {
             *      temp_list.Add(previous_list[nnn]);
             *  }
             *  // add between
             *  for (int j = 0; j < entrance_num - 1; j++)
             *  {
             *      // for the explanation: coincidence_positions_prev = prev, coincidence_positions_next = next
             *      // there are four options:
             *      // 1) prev[i+1] - prev[i] = 1 and next[i+1] - next[i] = 1 => temp_list.Add(previous_list[prev[i]])
             *      // 2) prev[i+1] - prev[i] > 1 and next[i+1] - next[i] = 1 => temp_list.Add(previous_list[prev[i]: prev[i+1] - 1])
             *      // 3) prev[i+1] - prev[i] = 1 and next[i+1] - next[i] > 1 => temp_list.Add(seen_points[n][next[i]: next[i+1] - 1])
             *      // 4) prev[i+1] - prev[i] > 1 and next[i+1] - next[i] > 1 => temp_list.Add(seen_points[n][next[i]: next[i+1] - 1], previous_list[prev[i]: prev[i+1] - 1])
             *
             *      // 1):
             *      if (coincidence_positions_prev[j + 1] - coincidence_positions_prev[j] == 1 &&
             *          coincidence_positions_next[j + 1] - coincidence_positions_next[j] == 1)
             *      {
             *          temp_list.Add(previous_list[coincidence_positions_prev[j]]);
             *      }
             *      // 2):
             *      if (coincidence_positions_prev[j + 1] - coincidence_positions_prev[j] > 1 &&
             *          coincidence_positions_next[j + 1] - coincidence_positions_next[j] == 1)
             *      {
             *          for (int jj = coincidence_positions_prev[j]; jj < coincidence_positions_prev[j+1]; jj++)
             *          {
             *              temp_list.Add(previous_list[jj]);
             *          }
             *      }
             *      // 3):
             *      if (coincidence_positions_prev[j + 1] - coincidence_positions_prev[j] == 1 &&
             *          coincidence_positions_next[j + 1] - coincidence_positions_next[j] > 1)
             *      {
             *          for (int jj = coincidence_positions_next[j]; jj < coincidence_positions_next[j + 1]; jj++)
             *          {
             *              temp_list.Add(seen_points[n][jj]);
             *          }
             *      }
             *      // 4):
             *      if (coincidence_positions_prev[j + 1] - coincidence_positions_prev[j] > 1 &&
             *          coincidence_positions_next[j + 1] - coincidence_positions_next[j] > 1)
             *      {
             *          for (int jj = coincidence_positions_next[j]; jj < coincidence_positions_next[j + 1]; jj++)
             *          {
             *              temp_list.Add(seen_points[n][jj]);
             *          }
             *          for (int jjj = coincidence_positions_prev[j]; jjj < coincidence_positions_prev[j + 1]; jjj++)
             *          {
             *              temp_list.Add(previous_list[jjj]);
             *          }
             *      }
             *  }
             *  // add everything from next_list after the last entrance
             *  for (int nnn = coincidence_positions_next[entrance_num - 1]; nnn < seen_points[n].Count; nnn++)
             *  {
             *      temp_list.Add(seen_points[n][nnn]);
             *  }
             *
             *  previous_list = temp_list;
             * }
             *
             *
             *
             *
             * List<Vector3> close_loop_repeats = new List<Vector3>();
             * close_loop_repeats.Add(previous_list[0].Coordinates);
             * Obj_List.Add("Obs point #" + 0 + ", " + previous_list[0].Coordinates.x + ", " + previous_list[0].Coordinates.y + ", " + previous_list[0].Coordinates.z);
             * for (int n = 1; n < previous_list.Count; n++)
             * {
             *  if (previous_list[0].Coordinates != previous_list[n].Coordinates)
             *  {
             *      close_loop_repeats.Add(previous_list[n].Coordinates);
             *      //Debug.DrawLine(previous_list[n - 1].Coordinates, previous_list[n].Coordinates, Color.red, 5.0f);
             *      Obj_List.Add("Obs point #" + n + ", " + previous_list[n].Coordinates.x + ", " + previous_list[n].Coordinates.y + ", " + previous_list[n].Coordinates.z);
             *  }
             *  else
             *  {
             *      //Debug.DrawLine(previous_list[n - 1].Coordinates, previous_list[n].Coordinates, Color.green, 5.0f);
             *      n = previous_list.Count;
             *  }
             *
             * }
             * //writePath = Application.dataPath + "/close_loop_points_norep" + ".csv";
             * //WriteFile(Obj_List, writePath);
             */
        }
    }
        public string IsError()
        {
            if (string.IsNullOrWhiteSpace(GrsName))
            {
                return("Укажите наименование ГРС");
            }
            if (string.IsNullOrWhiteSpace(SubGrsName))
            {
                return("Укажите наименование замерной нитки");
            }
            if (Psantimeter > 0)
            {
                if (V1 + V2 + V3 + V9 + V10 + V11 > 0)
                {
                    CalculateSmallK();
                }
                else
                {
                    K = SmallKConstants.KAll;
                }
            }
            else
            {
                if (V1 != 0 && !V1.CheckIntervalParams(90m, 97.9m))
                {
                    return("V1 параметр \"Объёмная концентрация метана\" несоответсвует");
                }
                if (V2 != 0 && !V2.CheckIntervalParams(0.75m, 4.75m))
                {
                    return("V2 параметр \"Объёмная концентрация этана\" несоответсвует");
                }
                if (V3 != 0 && !V3.CheckIntervalParams(0.30m, 3.5m))
                {
                    return("V3 параметр \"Объёмная концентрация пропана\" несоответсвует");
                }
                if (V4 != 0 && !V4.CheckIntervalParams(0.01m, 0.5m))
                {
                    return("V4 параметр \"Объёмная концентрация i-бутана\" несоответсвует");
                }
                if (!V5.CheckIntervalParams(0m, 0.4m))
                {
                    return("V5 параметр \"Объёмная концентрация n-бутана\" несоответсвует");
                }
                if (!V6.CheckIntervalParams(0m, 0.2m))
                {
                    return("V6 параметр \"Объёмная концентрация  i-пентана\" несоответсвует");
                }
                if (!V7.CheckIntervalParams(0m, 0.15m))
                {
                    return("V7 параметр \"Объёмная концентрация  n-пентана\" несоответсвует");
                }
                if (!V8.CheckIntervalParams(0m, 0.3m))
                {
                    return("V8 параметр \"Объёмная концентрация гексана\" несоответсвует");
                }
                if (V9 != 0 && !V9.CheckIntervalParams(0.1m, 2.5m))
                {
                    return("V9 параметр \"Объёмная концентрация углекислого газа\" несоответсвует");
                }
                if (V10 != 0 && !V10.CheckIntervalParams(0.2m, 1.3m))
                {
                    return("V10 параметр \"Объёмная концентрация азота\" несоответсвует");
                }
                if (!V11.CheckIntervalParams(0m, 0.3m))
                {
                    return("V11 параметр \"Объёмная концентрация кислорода\" несоответсвует");
                }

                if (K == 0)
                {
                    CalculateSmallK();
                }
                else if (!K.CheckIntervalParams(1.24m, 2.1m))
                {
                    return("k параметр \"Объёмный показатель адиабаты\" несоответсвует");
                }
                else
                {
                    this.IsCalculateK = false;
                }
            }

            if (Z == 0)
            {
                this.Z = 0.882m;
            }
            else if (!Z.CheckIntervalParams(0.6m, 0.9999m))
            {
                return("z параметр \"Коэффициент сжимаемости\" несоответсвует");
            }
            if (!Pvxod.CheckIntervalParams(0.01m, 6m))
            {
                return("Pвх параметр \"Давление газа на входе в ДГА\" несоответсвует");
            }
            if (!Pvixod.CheckIntervalParams(0.01m, 4m))
            {
                return("Pвых параметр \"Давление газа на выходе из ДГА\" несоответсвует");
            }
            if (!Q.CheckIntervalParams(100m, 100000000m))
            {
                return("Q параметр \"Расход газа по нитке\" несоответсвует");
            }
            if (!Temperature.CheckIntervalParams(10m, 90m))
            {
                return("t параметр \"Температура\" несоответсвует");
            }
            if ((Nnominal > 0 && EffectProcent == 0) || (Nnominal == 0 && EffectProcent > 0))
            {
                return("Укажите Nnominal и Procent, чтобы узнать эффективность расчета");
            }

            CalculateParams();
            return(string.Empty);
        }
    // Start is called before the first frame update
    void Start()
    {
        float                t_original  = Time.realtimeSinceStartup;
        GameObject           MPC_Spawner = GameObject.Find("MPC_spawner");
        Scatterers_Spawning2 MPC_Script  = MPC_Spawner.GetComponent <Scatterers_Spawning2>();
        List <Vector3>       MPC1        = MPC_Script.MPC1_possiblepositionList;
        List <Vector3>       MPC2        = MPC_Script.MPC2_possiblepositionList;
        List <Vector3>       MPC3        = MPC_Script.MPC3_possiblepositionList;
        List <Vector3>       DMC         = MPC_Script.DMC_possiblepositionList;


        // Declaring buildings and observation points
        Buildings = GameObject.FindGameObjectsWithTag("Reflecting_Obstacles");
        // The number of observation points should not be too big, a few is enough
        Observation_Points = GameObject.FindGameObjectsWithTag("Observation_Points");
        // Define the main road direction
        Vector3 main_axis = (Observation_Points[0].transform.position - Observation_Points[1].transform.position).normalized;
        Vector3 perp_axis = new Vector3(main_axis.z, 0, -main_axis.x);

        // subset of the seen Buldings
        List <GameObject> Building_list = new List <GameObject>();

        // Going through all observation points
        for (int k = 0; k < Observation_Points.Length; k++)
        {
            // analyzing which buidings are seen
            for (int b = 0; b < Buildings.Length; b++)
            {
                Vector3[] vrtx = Buildings[b].GetComponent <MeshFilter>().mesh.vertices;
                Vector3[] nrml = Buildings[b].GetComponent <MeshFilter>().mesh.normals;

                int seen_vrtx_count = 0;

                for (int v = 0; v < vrtx.Length; v++)
                {
                    if (vrtx[v].y == 0)
                    {
                        if (!Physics.Linecast(Observation_Points[k].transform.position, vrtx[v] + 1.1f * nrml[v]))
                        {
                            seen_vrtx_count += 1;
                        }
                    }
                }
                if (seen_vrtx_count != 0)
                {
                    if (!Building_list.Contains(Buildings[b]))
                    {
                        Building_list.Add(Buildings[b]);
                    }
                }
            }
        }

        // deactivating nonseen buildings
        for (int b = 0; b < Buildings.Length; b++)
        {
            if (!Building_list.Contains(Buildings[b]))
            {
                Buildings[b].SetActive(false);
            }
        }
        Debug.Log("The number of seen Buildings = " + Building_list.Count);

        List <Vector3> GlobalMPC1 = new List <Vector3>();

        List <Vector3> GlobalMPC2 = new List <Vector3>();

        List <Vector3> GlobalMPC3 = new List <Vector3>();

        List <Vector3> GlobalDMC = new List <Vector3>();

        // analyzing each seen building separately
        for (int k = 0; k < Building_list.Count; k++)
        {
            // writing MPCs into a txt file
            //string writePath;
            List <string> Obj_List = new List <string>();

            Vector3[] vrtx = Building_list[k].GetComponent <MeshFilter>().mesh.vertices;
            Vector3[] nrml = Building_list[k].GetComponent <MeshFilter>().mesh.normals;

            List <Vector3> floor_vrtx = new List <Vector3>();
            List <Vector3> floor_nrml = new List <Vector3>();
            var            pairs      = new List <V6>();

            List <Vector3> possible_vrtx = new List <Vector3>();
            List <Vector3> possible_nrml = new List <Vector3>();



            for (int l = 0; l < vrtx.Length; l++)
            {
                if (vrtx[l].y == 0 && Mathf.Abs(nrml[l].y) < 0.9)
                {
                    floor_vrtx.Add(vrtx[l]);
                    floor_nrml.Add(nrml[l]);

                    // adding coordinates and normals of the vertices into a single object V6 (like a N x 6 matrix)
                    V6 valid_pair = new V6(vrtx[l], nrml[l]);
                    pairs.Add(valid_pair);
                }
            }
            // finding the edges of each building
            List <Vector3> SortedByX = floor_vrtx.OrderBy(vertex => vertex.x).ToList();
            List <Vector3> SortedByZ = floor_vrtx.OrderBy(vertex => vertex.z).ToList();
            float          x_l       = SortedByX[0].x - WW2;                   // x left
            float          x_r       = SortedByX[SortedByX.Count - 1].x + WW2; // x right
            float          z_d       = SortedByZ[0].z - WW2;                   // z down
            float          z_u       = SortedByZ[SortedByX.Count - 1].z + WW2; // z up

            // searching which scatterers are located near the building
            NearbyElements(x_l, x_r, z_d, z_u, MPC1, out List <Vector3> NearbyMPC1);
            NearbyElements(x_l, x_r, z_d, z_u, MPC2, out List <Vector3> NearbyMPC2);
            NearbyElements(x_l, x_r, z_d, z_u, MPC3, out List <Vector3> NearbyMPC3);
            NearbyElements(x_l, x_r, z_d, z_u, DMC, out List <Vector3> NearbyDMC);

            //////////////////////////////////////////////////////////////////////////////////////////////////////////
            /// Defining areas around building where scatterers can be located
            //////////////////////////////////////////////////////////////////////////////////////////////////////////



            // defining necessary elements for the polygon that connects the last and the first vertices
            Vector3 n1_0     = floor_nrml[floor_vrtx.Count - 1];
            Vector3 p1_0     = floor_vrtx[floor_vrtx.Count - 1];
            Vector3 s1_0     = floor_vrtx[floor_vrtx.Count - 1] + WW1 * floor_nrml[floor_vrtx.Count - 1];
            Vector3 dmc_s1_0 = floor_vrtx[floor_vrtx.Count - 1] + WW2 * floor_nrml[floor_vrtx.Count - 1];

            Vector3 n2_0     = floor_nrml[0];
            Vector3 p2_0     = floor_vrtx[0];
            Vector3 s2_0     = floor_vrtx[0] + WW1 * floor_nrml[0];
            Vector3 dmc_s2_0 = floor_vrtx[0] + WW2 * floor_nrml[0];


            Area34 area = new Area34(p1_0, s1_0, p2_0, s2_0);
            //DrawArea(area);

            PickMPC(n1_0, p1_0, s1_0, n2_0, p2_0, s2_0, NearbyMPC1, out List <V6> MPC1_V6);
            PickMPC(n1_0, p1_0, s1_0, n2_0, p2_0, s2_0, NearbyMPC2, out List <V6> MPC2_V6);
            PickMPC(n1_0, p1_0, s1_0, n2_0, p2_0, s2_0, NearbyMPC3, out List <V6> MPC3_V6);
            PickMPC(n1_0, p1_0, dmc_s1_0, n2_0, p2_0, dmc_s2_0, NearbyMPC3, out List <V6> DMC_V6);


            //int MPC1_num = 0;
            for (int ii = 0; ii < MPC1_V6.Count; ii++)
            {
                if (!GlobalMPC1.Contains(MPC1_V6[ii].Coordinates))
                {
                    SeenV6_MPC1.Add(MPC1_V6[ii]);
                    V7 tempV7_MPC1 = new V7(MPC1_V6[ii], MPC1_num);
                    SeenV7_MPC1.Add(tempV7_MPC1);
                    GlobalMPC1.Add(MPC1_V6[ii].Coordinates);

                    //Entity newMPC1Entity = entityManager.Instantiate(MPC1_entity);
                    //entityManager.SetComponentData(newMPC1Entity, new Position);

                    //EntityManager.SetComponentData(newMPC1Entity, new Translation { Value = MPC1_V6[ii].Coordinates }) ;
                    //MPC1_Prefab.transform.position = MPC1_V6[ii].Coordinates;

                    if (MPC_visualizer_ECS == true)
                    {
                        GameObject MPC1_clone = Instantiate(MPC1_Prefab, MPC1_V6[ii].Coordinates, Quaternion.identity);
                        MPC1_clone.name = "mpc1 #" + MPC1_num;
                    }

                    MPC1_num += 1;
                }
            }

            //int MPC2_num = 0;
            for (int ii = 0; ii < MPC2_V6.Count; ii++)
            {
                if (!GlobalMPC2.Contains(MPC2_V6[ii].Coordinates))
                {
                    SeenV6_MPC2.Add(MPC2_V6[ii]);
                    V7 tempV7_MPC2 = new V7(MPC2_V6[ii], MPC2_num);
                    SeenV7_MPC2.Add(tempV7_MPC2);
                    GlobalMPC2.Add(MPC2_V6[ii].Coordinates);

                    if (MPC_visualizer_ECS == true)
                    {
                        GameObject MPC2_clone = Instantiate(MPC2_Prefab, MPC2_V6[ii].Coordinates, Quaternion.identity);
                        MPC2_clone.name = "mpc2 #" + MPC2_num;
                    }

                    MPC2_num += 1;
                }
            }

            //int MPC3_num = 0;
            for (int ii = 0; ii < MPC3_V6.Count; ii++)
            {
                if (!GlobalMPC3.Contains(MPC3_V6[ii].Coordinates))
                {
                    SeenV6_MPC3.Add(MPC3_V6[ii]);
                    V7 tempV7_MPC3 = new V7(MPC3_V6[ii], MPC3_num);
                    SeenV7_MPC3.Add(tempV7_MPC3);
                    GlobalMPC3.Add(MPC3_V6[ii].Coordinates);

                    if (MPC_visualizer_ECS == true)
                    {
                        GameObject MPC3_clone = Instantiate(MPC3_Prefab, MPC3_V6[ii].Coordinates, Quaternion.identity);
                        MPC3_clone.name = "mpc3 #" + MPC3_num;
                    }

                    MPC3_num += 1;
                }
            }
            //int DMC_num = 0;
            for (int ii = 0; ii < DMC_V6.Count; ii++)
            {
                if (!GlobalDMC.Contains(DMC_V6[ii].Coordinates))
                {
                    SeenV6_DMC.Add(DMC_V6[ii]);
                    V7 tempV7_DMC = new V7(DMC_V6[ii], DMC_num);
                    SeenV7_DMC.Add(tempV7_DMC);
                    GlobalDMC.Add(DMC_V6[ii].Coordinates);

                    if (MPC_visualizer_ECS == true)
                    {
                        GameObject DMC_clone = Instantiate(DMC_Prefab, DMC_V6[ii].Coordinates, Quaternion.identity);
                        DMC_clone.name = "mpc3 #" + DMC_num;
                    }

                    DMC_num += 1;
                }
            }



            // draw areas for all vertices
            Vector3 point1     = new Vector3(0.0f, 0.0f, 0.0f);
            Vector3 point2     = new Vector3(0.0f, 0.0f, 0.0f);
            Vector3 shift1     = new Vector3(0.0f, 0.0f, 0.0f);
            Vector3 shift2     = new Vector3(0.0f, 0.0f, 0.0f);
            Vector3 dmc_shift1 = new Vector3(0.0f, 0.0f, 0.0f);
            Vector3 dmc_shift2 = new Vector3(0.0f, 0.0f, 0.0f);

            for (int l = 0; l < floor_vrtx.Count - 1; l++)
            {
                point1 = floor_vrtx[l];
                point2 = floor_vrtx[l + 1];

                shift1 = floor_vrtx[l] + WW1 * floor_nrml[l];
                shift2 = floor_vrtx[l + 1] + WW1 * floor_nrml[l + 1];

                dmc_shift1 = floor_vrtx[l] + WW2 * floor_nrml[l];
                dmc_shift2 = floor_vrtx[l + 1] + WW2 * floor_nrml[l + 1];

                Area34 area_forloop = new Area34(point1, dmc_shift1, point2, dmc_shift2);
                //DrawArea(area_forloop);

                PickMPC(floor_nrml[l], point1, shift1, floor_nrml[l + 1], point2, shift2, NearbyMPC1, out List <V6> for_MPC1_V6);
                PickMPC(floor_nrml[l], point1, shift1, floor_nrml[l + 1], point2, shift2, NearbyMPC2, out List <V6> for_MPC2_V6);
                PickMPC(floor_nrml[l], point1, shift1, floor_nrml[l + 1], point2, shift2, NearbyMPC3, out List <V6> for_MPC3_V6);
                // picking DMCs
                PickMPC(floor_nrml[l], point1, dmc_shift1, floor_nrml[l + 1], point2, dmc_shift2, NearbyDMC, out List <V6> for_DMC_V6);

                // MPC1
                for (int ii = 0; ii < for_MPC1_V6.Count; ii++)
                {
                    if (!GlobalMPC1.Contains(for_MPC1_V6[ii].Coordinates))
                    {
                        SeenV6_MPC1.Add(for_MPC1_V6[ii]);
                        V7 tempV7_MPC1 = new V7(for_MPC1_V6[ii], MPC1_num);
                        SeenV7_MPC1.Add(tempV7_MPC1);
                        GlobalMPC1.Add(for_MPC1_V6[ii].Coordinates);

                        if (MPC_visualizer_ECS == true)
                        {
                            GameObject clone = Instantiate(MPC1_Prefab, for_MPC1_V6[ii].Coordinates, Quaternion.identity);
                            clone.name = "mpc1 #" + MPC1_num;
                        }

                        MPC1_num += 1;
                    }
                }
                // MPC2
                for (int ii = 0; ii < for_MPC2_V6.Count; ii++)
                {
                    if (!GlobalMPC2.Contains(for_MPC2_V6[ii].Coordinates))
                    {
                        SeenV6_MPC2.Add(for_MPC2_V6[ii]);
                        V7 tempV7_MPC2 = new V7(for_MPC2_V6[ii], MPC2_num);
                        SeenV7_MPC2.Add(tempV7_MPC2);
                        GlobalMPC2.Add(for_MPC2_V6[ii].Coordinates);

                        if (MPC_visualizer_ECS == true)
                        {
                            GameObject MPC2_clone = Instantiate(MPC2_Prefab, for_MPC2_V6[ii].Coordinates, Quaternion.identity);
                            MPC2_clone.name = "mpc2 #" + MPC2_num;
                        }

                        MPC2_num += 1;
                    }
                }
                // MPC3
                for (int ii = 0; ii < for_MPC3_V6.Count; ii++)
                {
                    if (!GlobalMPC3.Contains(for_MPC3_V6[ii].Coordinates))
                    {
                        SeenV6_MPC3.Add(for_MPC3_V6[ii]);
                        V7 tempV7_MPC3 = new V7(for_MPC3_V6[ii], MPC3_num);
                        SeenV7_MPC3.Add(tempV7_MPC3);
                        GlobalMPC3.Add(for_MPC3_V6[ii].Coordinates);

                        if (MPC_visualizer_ECS == true)
                        {
                            GameObject MPC3_clone = Instantiate(MPC3_Prefab, for_MPC3_V6[ii].Coordinates, Quaternion.identity);
                            MPC3_clone.name = "mpc3 #" + MPC3_num;
                        }

                        MPC3_num += 1;
                    }
                }

                // DMCs
                for (int ii = 0; ii < for_DMC_V6.Count; ii++)
                {
                    if (!GlobalDMC.Contains(for_DMC_V6[ii].Coordinates))
                    {
                        SeenV6_DMC.Add(for_DMC_V6[ii]);
                        V7 tempV7_DMC = new V7(for_DMC_V6[ii], DMC_num);
                        SeenV7_DMC.Add(tempV7_DMC);
                        GlobalDMC.Add(for_DMC_V6[ii].Coordinates);

                        if (MPC_visualizer_ECS == true)
                        {
                            GameObject DMC_clone = Instantiate(DMC_Prefab, for_DMC_V6[ii].Coordinates, Quaternion.identity);
                            DMC_clone.name = "dmc #" + DMC_num;
                        }

                        DMC_num += 1;
                    }
                }
            }



            //Area2D(vv1, vv2, out float S11);
        }
        Debug.Log("Number of seen MPC1 = " + SeenV7_MPC1.Count + "; check number " + MPC1_num);
        Debug.Log("Number of seen MPC2 = " + SeenV7_MPC2.Count + "; check number " + MPC2_num);
        Debug.Log("Number of seen MPC3 = " + SeenV7_MPC3.Count + "; check number " + MPC3_num);
        Debug.Log("Number of seen DMCs = " + SeenV7_DMC.Count + "; check number " + DMC_num);

        Debug.Log("Check Time t_original: " + ((Time.realtimeSinceStartup - t_original) * 1000f) + " ms");
    }
Пример #16
0
    // Start is called before the first frame update
    void Start()
    {
        float                t_native    = Time.realtimeSinceStartup;
        GameObject           MPC_Spawner = GameObject.Find("MPC_spawner");
        Scatterers_Spawning2 MPC_Script  = MPC_Spawner.GetComponent <Scatterers_Spawning2>();
        List <Vector3>       MPC1        = MPC_Script.MPC1_possiblepositionList;
        List <Vector3>       MPC2        = MPC_Script.MPC2_possiblepositionList;
        List <Vector3>       MPC3        = MPC_Script.MPC3_possiblepositionList;

        NativeList <V4>       MPC1_Native = MPC_Script.MPC1_possiblepositionNativeList;
        NativeList <V4>       MPC2_Native = MPC_Script.MPC2_possiblepositionNativeList;
        NativeList <V4>       MPC3_Native = MPC_Script.MPC3_possiblepositionNativeList;
        NativeList <V4>       DMC_Native  = MPC_Script.DMC_possiblepositionNativeList;
        NativeArray <Vector3> OBS_Native  = MPC_Script.Observation_Points_NativeArray;

        NativeList <V5> MPC_Native = MPC_Script.MPC_possiblepositionNativeList;



        // Declaring buildings and observation points
        Buildings = GameObject.FindGameObjectsWithTag("Reflecting_Obstacles");
        // The number of observation points should not be too big, a few is enough
        //Observation_Points = GameObject.FindGameObjectsWithTag("Observation_Points");
        // Define the main road direction
        //Vector3 main_axis = (Observation_Points[0].transform.position - Observation_Points[1].transform.position).normalized;
        Vector3 main_axis = (OBS_Native[0] - OBS_Native[1]).normalized;
        Vector3 perp_axis = new Vector3(main_axis.z, 0, -main_axis.x);

        // subset of the seen Buldings
        List <GameObject> Building_list = new List <GameObject>();

        // Going through all observation points
        for (int k = 0; k < OBS_Native.Length; k++)
        {
            // analyzing which buidings are seen
            for (int b = 0; b < Buildings.Length; b++)
            {
                Vector3[] vrtx = Buildings[b].GetComponent <MeshFilter>().mesh.vertices;
                Vector3[] nrml = Buildings[b].GetComponent <MeshFilter>().mesh.normals;

                int seen_vrtx_count = 0;

                for (int v = 0; v < vrtx.Length; v++)
                {
                    if (vrtx[v].y == 0)
                    {
                        //if (!Physics.Linecast(Observation_Points[k].transform.position, vrtx[v] + 1.1f * nrml[v]))
                        if (!Physics.Linecast(OBS_Native[k], vrtx[v] + 1.1f * nrml[v]))
                        {
                            seen_vrtx_count += 1;
                        }
                    }
                }
                if (seen_vrtx_count != 0)
                {
                    if (!Building_list.Contains(Buildings[b]))
                    {
                        Building_list.Add(Buildings[b]);
                    }
                }
            }
        }

        // deactivating nonseen buildings
        for (int b = 0; b < Buildings.Length; b++)
        {
            if (!Building_list.Contains(Buildings[b]))
            {
                Buildings[b].SetActive(false);
            }
        }
        Debug.Log("The number of seen Buildings = " + Building_list.Count);

        List <Vector3> GlobalMPC1 = new List <Vector3>();
        List <Vector3> GlobalMPC2 = new List <Vector3>();
        List <Vector3> GlobalMPC3 = new List <Vector3>();
        List <Vector3> GlobalDMC  = new List <Vector3>();

        // int inclusion_count = 0;
        // analyzing each seen building separately
        NativeArray <V6> MPC1_Pick = new NativeArray <V6>(MPC1_Native.Length, Allocator.TempJob);
        NativeArray <V6> MPC2_Pick = new NativeArray <V6>(MPC2_Native.Length, Allocator.TempJob);
        NativeArray <V6> MPC3_Pick = new NativeArray <V6>(MPC3_Native.Length, Allocator.TempJob);
        NativeArray <V6> DMC_Pick  = new NativeArray <V6>(DMC_Native.Length, Allocator.TempJob);
        // perpendicular directions
        NativeArray <Vector3> MPC1_Pick_perp = new NativeArray <Vector3>(MPC1_Native.Length, Allocator.TempJob);
        NativeArray <Vector3> MPC2_Pick_perp = new NativeArray <Vector3>(MPC2_Native.Length, Allocator.TempJob);
        NativeArray <Vector3> MPC3_Pick_perp = new NativeArray <Vector3>(MPC3_Native.Length, Allocator.TempJob);
        NativeArray <Vector3> DMC_Pick_perp  = new NativeArray <Vector3>(DMC_Native.Length, Allocator.TempJob);



        for (int k = 0; k < Building_list.Count; k++)
        {
            // writing MPCs into a txt file
            //string writePath;
            List <string> Obj_List = new List <string>();

            Vector3[] vrtx = Building_list[k].GetComponent <MeshFilter>().mesh.vertices;
            Vector3[] nrml = Building_list[k].GetComponent <MeshFilter>().mesh.normals;



            List <Vector3> floor_vrtx = new List <Vector3>();
            List <Vector3> floor_nrml = new List <Vector3>();
            var            pairs      = new List <V6>();

            List <Vector3> possible_vrtx = new List <Vector3>();
            List <Vector3> possible_nrml = new List <Vector3>();



            for (int l = 0; l < vrtx.Length; l++)
            {
                if (vrtx[l].y == 0 && Mathf.Abs(nrml[l].y) < 0.9)
                {
                    floor_vrtx.Add(vrtx[l]);
                    floor_nrml.Add(nrml[l]);

                    // adding coordinates and normals of the vertices into a single object V6 (like a N x 6 matrix)
                    V6 valid_pair = new V6(vrtx[l], nrml[l]);
                    pairs.Add(valid_pair);
                }
            }


            // finding the edges of each building
            List <Vector3> SortedByX = floor_vrtx.OrderBy(vertex => vertex.x).ToList();
            List <Vector3> SortedByZ = floor_vrtx.OrderBy(vertex => vertex.z).ToList();
            float          x_l       = SortedByX[0].x - WW2;                   // x left
            float          x_r       = SortedByX[SortedByX.Count - 1].x + WW2; // x right
            float          z_d       = SortedByZ[0].z - WW2;                   // z down
            float          z_u       = SortedByZ[SortedByX.Count - 1].z + WW2; // z up

            // This procedure is needed for defining the corner the building for further Diffraction simulation
            string building_name = Building_list[k].name;

            Vector3 corner1 = new Vector3(0, 0, 0);
            Vector3 normal1 = new Vector3(0, 0, 0);
            Vector3 perpen1 = new Vector3(0, 0, 0);

            Vector3 corner2 = new Vector3(0, 0, 0);
            Vector3 normal2 = new Vector3(0, 0, 0);
            Vector3 perpen2 = new Vector3(0, 0, 0);

            if (building_name == "Building258")
            {
                Debug.Log(building_name);
                corner1 = SortedByX[2];
                corner2 = SortedByX[6];

                GameObject Corner1 = Instantiate(CornerPrefab, corner1, Quaternion.identity);
                GameObject Corner2 = Instantiate(MPC1_Prefab, corner2, Quaternion.identity);

                int corner1_count = 0;
                for (int v = 0; v < floor_vrtx.Count; v++)
                {
                    if (corner1 == floor_vrtx[v])
                    {
                        if (corner1_count == 0)
                        {
                            normal1       = floor_nrml[v]; // I use the assumption that the vertex is used only twice
                            corner1_count = 1;
                        }
                    }
                    if (corner2 == floor_vrtx[v])
                    {
                        normal2 = floor_nrml[v]; // I use the assumption that the vertex is used only twice
                    }
                }
                normal1 = normal1.normalized;
                perpen1 = new Vector3(-normal1.z, 0, normal1.x);
                Debug.DrawLine(corner1, corner1 + 5 * normal1, Color.red, 30f);

                normal2 = normal2.normalized;
                perpen2 = new Vector3(-normal2.z, 0, normal2.x);
                Debug.DrawLine(corner2, corner2 + 5 * normal2, Color.red, 30f);



                Active_CornersNormalsPerpendiculars.Add(corner1);
                Active_CornersNormalsPerpendiculars.Add(normal1);
                Active_CornersNormalsPerpendiculars.Add(perpen1);

                Active_CornersNormalsPerpendiculars.Add(corner2);
                Active_CornersNormalsPerpendiculars.Add(normal2);
                Active_CornersNormalsPerpendiculars.Add(perpen2);

                // this is done to model single edge building (keep in mind, multipath go through the angle)
                // Vector3 corner_test = (corner1 + corner2) / 2 + 3.0f * (normal1 + normal2) / 2;
                Vector3    corner_test = new Vector3(53.64f, 0.0f, -26.89f);
                GameObject Corner_Test = Instantiate(CornerPrefab, corner_test, Quaternion.identity);

                Active_CornersNormalsPerpendiculars.Add(corner_test);
            }

            /*
             * if (building_name == "Building321")
             * {
             *  Debug.Log(building_name);
             *  corner321 = SortedByX[SortedByX.Count - 1];
             *
             *  GameObject Corner321 = Instantiate(CornerPrefab, corner321, Quaternion.identity);
             *
             *  for (int v = 0; v < floor_vrtx.Count; v++)
             *  {
             *      if (corner321 == floor_vrtx[v])
             *      {
             *          normal321 += floor_nrml[v]; // I use the assumption that the vertex is used only twice
             *      }
             *  }
             *  normal321 = normal321.normalized;
             *  perpen321 = new Vector3(-normal321.z, 0, normal321.x);
             *  Debug.DrawLine(corner321, corner321 + 5 * normal321, Color.red, 30f);
             *
             *  Active_CornersNormalsPerpendiculars.Add(corner321);
             *  Active_CornersNormalsPerpendiculars.Add(normal321);
             *  Active_CornersNormalsPerpendiculars.Add(perpen321);
             * }
             * if (building_name == "Building334")
             * {
             *  Debug.Log(building_name);
             *  corner334 = SortedByX[0];
             *  GameObject Corner334 = Instantiate(CornerPrefab, corner334, Quaternion.identity);
             *
             *  for (int v = 0; v < floor_vrtx.Count; v++)
             *  {
             *      if (corner334 == floor_vrtx[v])
             *      {
             *          normal334 += floor_nrml[v]; // I use the assumption that the vertex is used only twice
             *      }
             *  }
             *  normal334 = normal334.normalized;
             *  perpen334 = new Vector3(-normal334.z, 0, normal334.x);
             *  Debug.DrawLine(corner334, corner334 + 5 * normal334, Color.red, 30f);
             *
             *  Active_CornersNormalsPerpendiculars.Add(corner334);
             *  Active_CornersNormalsPerpendiculars.Add(normal334);
             *  Active_CornersNormalsPerpendiculars.Add(perpen334);
             * }
             */

            //////////////////////////////////////////////////////////////////////////////////////////////////////////
            /// Defining areas around building where scatterers can be located
            //////////////////////////////////////////////////////////////////////////////////////////////////////////



            // defining necessary elements for the polygon that connects the last and the first vertices
            Vector3 n1_0     = floor_nrml[floor_vrtx.Count - 1];
            Vector3 p1_0     = floor_vrtx[floor_vrtx.Count - 1];
            Vector3 s1_0     = floor_vrtx[floor_vrtx.Count - 1] + WW1 * floor_nrml[floor_vrtx.Count - 1];
            Vector3 s1_0_dmc = floor_vrtx[floor_vrtx.Count - 1] + WW2 * floor_nrml[floor_vrtx.Count - 1];

            Vector3 n2_0     = floor_nrml[0];
            Vector3 p2_0     = floor_vrtx[0];
            Vector3 s2_0     = floor_vrtx[0] + WW1 * floor_nrml[0];
            Vector3 s2_0_dmc = floor_vrtx[0] + WW2 * floor_nrml[0];

            Area34 area = new Area34(p1_0, s1_0, p2_0, s2_0);



            //float t1 = Time.realtimeSinceStartup;
            // MPC1
            PickMPCParallel pickMPCParallel1 = new PickMPCParallel
            {
                n1 = n1_0,
                p1 = p1_0,
                s1 = s1_0,
                n2 = n2_0,
                p2 = p2_0,
                s2 = s2_0,

                Xleft  = x_l,
                Xright = x_r,
                Zdown  = z_d,
                Zup    = z_u,

                MPC_array = MPC1_Native,
                MPC_V6    = MPC1_Pick,
                MPC_perp  = MPC1_Pick_perp,
            };
            JobHandle jobHandle_Pick1 = pickMPCParallel1.Schedule(MPC1_Native.Length, 100);
            // MPC2
            PickMPCParallel pickMPCParallel2 = new PickMPCParallel
            {
                n1 = n1_0,
                p1 = p1_0,
                s1 = s1_0,
                n2 = n2_0,
                p2 = p2_0,
                s2 = s2_0,

                Xleft  = x_l,
                Xright = x_r,
                Zdown  = z_d,
                Zup    = z_u,

                MPC_array = MPC2_Native,
                MPC_V6    = MPC2_Pick,
                MPC_perp  = MPC2_Pick_perp,
            };
            JobHandle jobHandle_Pick2 = pickMPCParallel2.Schedule(MPC2_Native.Length, 100, jobHandle_Pick1);
            // MPC3
            PickMPCParallel pickMPCParallel3 = new PickMPCParallel
            {
                n1 = n1_0,
                p1 = p1_0,
                s1 = s1_0,
                n2 = n2_0,
                p2 = p2_0,
                s2 = s2_0,

                Xleft  = x_l,
                Xright = x_r,
                Zdown  = z_d,
                Zup    = z_u,

                MPC_array = MPC3_Native,
                MPC_V6    = MPC3_Pick,
                MPC_perp  = MPC3_Pick_perp,
            };
            JobHandle jobHandle_Pick3 = pickMPCParallel3.Schedule(MPC3_Native.Length, 100, jobHandle_Pick2);
            // DMC
            PickMPCParallel pickMPCParallel4 = new PickMPCParallel
            {
                n1 = n1_0,
                p1 = p1_0,
                s1 = s1_0_dmc,
                n2 = n2_0,
                p2 = p2_0,
                s2 = s2_0_dmc,

                Xleft  = x_l,
                Xright = x_r,
                Zdown  = z_d,
                Zup    = z_u,

                MPC_array = DMC_Native,
                MPC_V6    = DMC_Pick,
                MPC_perp  = DMC_Pick_perp,
            };
            JobHandle jobHandle_Pick4 = pickMPCParallel4.Schedule(DMC_Native.Length, 100, jobHandle_Pick3);

            jobHandle_Pick1.Complete();
            jobHandle_Pick2.Complete();
            jobHandle_Pick3.Complete();
            jobHandle_Pick4.Complete();

            //Debug.Log("Check Time t1: " + ((Time.realtimeSinceStartup - t1) * 1000f) + " ms");


            // draw areas for all vertices
            Vector3 point1     = new Vector3(0.0f, 0.0f, 0.0f);
            Vector3 point2     = new Vector3(0.0f, 0.0f, 0.0f);
            Vector3 shift1     = new Vector3(0.0f, 0.0f, 0.0f);
            Vector3 shift2     = new Vector3(0.0f, 0.0f, 0.0f);
            Vector3 dmc_shift1 = new Vector3(0.0f, 0.0f, 0.0f);
            Vector3 dmc_shift2 = new Vector3(0.0f, 0.0f, 0.0f);

            for (int l = 0; l < floor_vrtx.Count - 1; l++)
            {
                point1 = floor_vrtx[l];
                point2 = floor_vrtx[l + 1];

                shift1 = floor_vrtx[l] + WW1 * floor_nrml[l];
                shift2 = floor_vrtx[l + 1] + WW1 * floor_nrml[l + 1];

                dmc_shift1 = floor_vrtx[l] + WW2 * floor_nrml[l];
                dmc_shift2 = floor_vrtx[l + 1] + WW2 * floor_nrml[l + 1];


                Area34 area_forloop = new Area34(point1, dmc_shift1, point2, dmc_shift2);
                //DrawArea(area_forloop);

                // MPC1
                PickMPCParallel pickMPCParallel_for = new PickMPCParallel
                {
                    n1 = floor_nrml[l],
                    p1 = point1,
                    s1 = shift1,
                    n2 = floor_nrml[l + 1],
                    p2 = point2,
                    s2 = shift2,

                    Xleft  = x_l,
                    Xright = x_r,
                    Zdown  = z_d,
                    Zup    = z_u,

                    MPC_array = MPC1_Native,
                    MPC_V6    = MPC1_Pick,
                    MPC_perp  = MPC1_Pick_perp,
                };
                JobHandle jobHandle_Pick1_for = pickMPCParallel_for.Schedule(MPC1_Native.Length, 100);
                // MPC2
                PickMPCParallel pickMPCParallel2_for = new PickMPCParallel
                {
                    n1 = floor_nrml[l],
                    p1 = point1,
                    s1 = shift1,
                    n2 = floor_nrml[l + 1],
                    p2 = point2,
                    s2 = shift2,

                    Xleft  = x_l,
                    Xright = x_r,
                    Zdown  = z_d,
                    Zup    = z_u,

                    MPC_array = MPC2_Native,
                    MPC_V6    = MPC2_Pick,
                    MPC_perp  = MPC2_Pick_perp,
                };
                JobHandle jobHandle_Pick2_for = pickMPCParallel2_for.Schedule(MPC2_Native.Length, 100, jobHandle_Pick1_for);
                // MPC3
                PickMPCParallel pickMPCParallel3_for = new PickMPCParallel
                {
                    n1 = floor_nrml[l],
                    p1 = point1,
                    s1 = shift1,
                    n2 = floor_nrml[l + 1],
                    p2 = point2,
                    s2 = shift2,

                    Xleft  = x_l,
                    Xright = x_r,
                    Zdown  = z_d,
                    Zup    = z_u,

                    MPC_array = MPC3_Native,
                    MPC_V6    = MPC3_Pick,
                    MPC_perp  = MPC3_Pick_perp,
                };
                JobHandle jobHandle_Pick3_for = pickMPCParallel3_for.Schedule(MPC3_Native.Length, 100, jobHandle_Pick2_for);
                // DMC
                PickMPCParallel pickMPCParallel4_for = new PickMPCParallel
                {
                    n1 = floor_nrml[l],
                    p1 = point1,
                    s1 = dmc_shift1,
                    n2 = floor_nrml[l + 1],
                    p2 = point2,
                    s2 = dmc_shift2,

                    Xleft  = x_l,
                    Xright = x_r,
                    Zdown  = z_d,
                    Zup    = z_u,

                    MPC_array = DMC_Native,
                    MPC_V6    = DMC_Pick,
                    MPC_perp  = DMC_Pick_perp,
                };
                JobHandle jobHandle_Pick4_for = pickMPCParallel4_for.Schedule(DMC_Native.Length, 100, jobHandle_Pick3_for);

                jobHandle_Pick1_for.Complete();
                jobHandle_Pick2_for.Complete();
                jobHandle_Pick3_for.Complete();
                jobHandle_Pick4_for.Complete();
            }
        }

        //float t_seq = Time.realtimeSinceStartup;
        // DMC
        int inclusion_num0 = 0;

        for (int ii = 0; ii < DMC_Native.Length; ii++)
        {
            if (DMC_Native[ii].Inclusion == 1)
            {
                inclusion_num0 += 1;
                ActiveV6_DMC_NativeList.Add(DMC_Pick[ii]); // DMCs only
                ActiveV6_MPC_NativeList.Add(DMC_Pick[ii]); // all MPCs
                // MPC perpendicular directions
                Active_DMC_Perpendiculars.Add(DMC_Pick_perp[ii]);
                Active_MPC_Perpendiculars.Add(DMC_Pick_perp[ii]);

                if (MPC_visualizer_ECS == true)
                {
                    GameObject DMC_clone = Instantiate(DMC_Prefab, DMC_Native[ii].Coordinates, Quaternion.identity);

                    //GameObject cleared_sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);

                    //cleared_sphere.transform.position = DMC_Native[ii].Coordinates;
                    //Destroy(cleared_sphere.GetComponent<SphereCollider>()); // remove collider
                    //cleared_sphere.name = "DMC #" + (inclusion_num4 - 1);

                    //Debug.DrawLine(DMC_Pick[ii].Coordinates, DMC_Pick[ii].Coordinates + 5*DMC_Pick[ii].Normal, Color.red, 30f);
                }
            }
        }

        // MPC1
        int inclusion_num1 = 0;

        for (int ii = 0; ii < MPC1_Native.Length; ii++)
        {
            if (MPC1_Native[ii].Inclusion == 1)
            {
                inclusion_num1 += 1;
                ActiveV6_MPC1_NativeList.Add(MPC1_Pick[ii]);
                ActiveV6_MPC_NativeList.Add(MPC1_Pick[ii]);

                // MPC perpendicular directions
                Active_MPC1_Perpendiculars.Add(MPC1_Pick_perp[ii]);
                Active_MPC_Perpendiculars.Add(MPC1_Pick_perp[ii]);

                if (MPC_visualizer_ECS == true)
                {
                    GameObject MPC1_clone = Instantiate(MPC1_Prefab, MPC1_Native[ii].Coordinates, Quaternion.identity);
                }
            }
        }

        // MPC2
        int inclusion_num2 = 0;

        for (int ii = 0; ii < MPC2_Native.Length; ii++)
        {
            if (MPC2_Native[ii].Inclusion == 1)
            {
                ActiveV6_MPC2_NativeList.Add(MPC2_Pick[ii]);
                ActiveV6_MPC_NativeList.Add(MPC2_Pick[ii]);
                // MPC perpendicular directions
                Active_MPC2_Perpendiculars.Add(MPC2_Pick_perp[ii]);
                Active_MPC_Perpendiculars.Add(MPC2_Pick_perp[ii]);

                if (MPC_visualizer_ECS == true)
                {
                    GameObject MPC2_clone = Instantiate(MPC2_Prefab, MPC2_Native[ii].Coordinates, Quaternion.identity);
                    MPC2_clone.name = "MPC2 # " + inclusion_num2;
                    //Debug.DrawLine(MPC2_Pick[ii].Coordinates, MPC2_Pick[ii].Coordinates + 5 * MPC2_Pick[ii].Normal, Color.cyan, 10f);
                    //Debug.DrawLine(MPC2_Pick[ii].Coordinates, MPC2_Pick[ii].Coordinates + 5 * MPC2_Pick_perp[ii], Color.yellow, 10f);
                }
                inclusion_num2 += 1;
            }
        }

        // MPC3
        int inclusion_num3 = 0;

        for (int ii = 0; ii < MPC3_Native.Length; ii++)
        {
            if (MPC3_Native[ii].Inclusion == 1)
            {
                ActiveV6_MPC3_NativeList.Add(MPC3_Pick[ii]);
                ActiveV6_MPC_NativeList.Add(MPC3_Pick[ii]);
                // MPC perpendicular directions
                Active_MPC3_Perpendiculars.Add(MPC3_Pick_perp[ii]);
                Active_MPC_Perpendiculars.Add(MPC3_Pick_perp[ii]);
                if (MPC_visualizer_ECS == true)
                {
                    GameObject MPC3_clone = Instantiate(MPC3_Prefab, MPC3_Native[ii].Coordinates, Quaternion.identity);
                    MPC3_clone.name = "MPC3 # " + inclusion_num3;
                    //Debug.DrawLine(MPC3_Pick[ii].Coordinates, MPC3_Pick[ii].Coordinates + 5 * MPC3_Pick[ii].Normal, Color.cyan, 10f);
                    //Debug.DrawLine(MPC3_Pick[ii].Coordinates, MPC3_Pick[ii].Coordinates + 5 * MPC3_Pick_perp[ii], Color.yellow, 10f);
                }
                inclusion_num3 += 1;
            }
        }

        //Debug.Log("Check Time for Sequ: " + ((Time.realtimeSinceStartup - t_seq) * 1000f) + " ms");
        Debug.Log("DMC " + inclusion_num0 + "; MPC1 " + inclusion_num1 + "; MPC2 " + inclusion_num2 + "; MPC3 " + inclusion_num3);


        #region Generating attenuation coefficients for MPCs
        // Power generation for MPCs
        ActiveV6_DMC_Power  = new NativeArray <float>(ActiveV6_DMC_NativeList.Length, Allocator.Persistent);
        ActiveV6_MPC1_Power = new NativeArray <float>(ActiveV6_MPC1_NativeList.Length, Allocator.Persistent);
        ActiveV6_MPC2_Power = new NativeArray <float>(ActiveV6_MPC2_NativeList.Length, Allocator.Persistent);
        ActiveV6_MPC3_Power = new NativeArray <float>(ActiveV6_MPC3_NativeList.Length, Allocator.Persistent);
        int MPC_length = ActiveV6_DMC_NativeList.Length + ActiveV6_MPC1_NativeList.Length + ActiveV6_MPC2_NativeList.Length + ActiveV6_MPC3_NativeList.Length;
        ActiveV6_MPC_Power = new NativeArray <float>(MPC_length, Allocator.Persistent);
        //int clbrcoef = 10;
        Vector2 DMCPower  = new Vector2(-80, -68); // + new Vector2(1,1) * clbrcoef; // (Mathf.Pow(10, (-80/20)), Mathf.Pow(10, (-68/20))); // (-80, -68)[dB] % Diffuse 1st)
        Vector2 MPC1Power = new Vector2(-65, -48); // (Mathf.Pow(10, (-65/20)), Mathf.Pow(10, (-48/20))); // (-65, -48)[dB] % 1st
        Vector2 MPC2Power = new Vector2(-70, -59); // (Mathf.Pow(10, (-70/20)), Mathf.Pow(10, (-59/20))); // (-70, -59)[dB] % 2nd
        Vector2 MPC3Power = new Vector2(-75, -65); // (Mathf.Pow(10, (-75/20)), Mathf.Pow(10, (-65/20))); // (-75, -65)[dB] % 3rd

        // this solution comes from https://forum.unity.com/threads/mathematics-random-with-in-ijobprocesscomponentdata.598192/#post-4009273
        NativeArray <Unity.Mathematics.Random> rngs = new NativeArray <Unity.Mathematics.Random>(JobsUtility.MaxJobThreadCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
        for (int i = 0; i < JobsUtility.MaxJobThreadCount; i++)
        {
            rngs[i] = new Unity.Mathematics.Random((uint)UnityEngine.Random.Range(int.MinValue, int.MaxValue));
        }

        MPCPowerGeneration dmcPowerGeneration = new MPCPowerGeneration
        {
            rngs   = rngs,
            MinMax = DMCPower,
            Array  = ActiveV6_DMC_Power,
        };
        JobHandle power0 = dmcPowerGeneration.Schedule(ActiveV6_DMC_Power.Length, 64);
        power0.Complete();
        for (int i = 0; i < ActiveV6_DMC_Power.Length; i++)
        {
            ActiveV6_MPC_Power[i] = ActiveV6_DMC_Power[i];
        }

        MPCPowerGeneration mpc1PowerGeneration = new MPCPowerGeneration
        {
            rngs   = rngs,
            MinMax = MPC1Power,
            Array  = ActiveV6_MPC1_Power,
        };
        JobHandle power1 = mpc1PowerGeneration.Schedule(ActiveV6_MPC1_Power.Length, 64);
        power1.Complete();
        for (int i = 0; i < ActiveV6_MPC1_Power.Length; i++)
        {
            ActiveV6_MPC_Power[i + ActiveV6_DMC_Power.Length] = ActiveV6_MPC1_Power[i];
        }

        MPCPowerGeneration mpc2PowerGeneration = new MPCPowerGeneration
        {
            rngs   = rngs,
            MinMax = MPC2Power,
            Array  = ActiveV6_MPC2_Power,
        };
        JobHandle power2 = mpc2PowerGeneration.Schedule(ActiveV6_MPC2_Power.Length, 64);
        power2.Complete();
        for (int i = 0; i < ActiveV6_MPC2_Power.Length; i++)
        {
            ActiveV6_MPC_Power[i + ActiveV6_DMC_Power.Length + ActiveV6_MPC1_Power.Length] = Mathf.Pow(ActiveV6_MPC2_Power[i], 0.5f);   // It seems that Carl uses only one multiplication to the coefficient
            ActiveV6_MPC2_Power[i] = Mathf.Pow(ActiveV6_MPC2_Power[i], 0.5f);

            float asd = ActiveV6_MPC2_Power[i];
            float zxc = Mathf.Pow(asd, 0.5f);
            //float qwe = 1.0f;
        }


        MPCPowerGeneration mpc3PowerGeneration = new MPCPowerGeneration
        {
            rngs   = rngs,
            MinMax = MPC3Power,
            Array  = ActiveV6_MPC3_Power,
        };
        JobHandle power3 = mpc3PowerGeneration.Schedule(ActiveV6_MPC3_Power.Length, 64);
        power3.Complete();
        for (int i = 0; i < ActiveV6_MPC3_Power.Length; i++)
        {
            float asd = ActiveV6_MPC3_Power[i];
            float zxc = Mathf.Pow(ActiveV6_MPC3_Power[i], 0.3333f);
            ActiveV6_MPC_Power[i + ActiveV6_DMC_Power.Length + ActiveV6_MPC1_Power.Length + ActiveV6_MPC2_Power.Length] = Mathf.Pow(ActiveV6_MPC3_Power[i], 0.3333f);   // It seems that Carl uses only one multiplication to the coefficient
            ActiveV6_MPC3_Power[i] = Mathf.Pow(ActiveV6_MPC3_Power[i], 0.3333f);
        }
        #endregion



        MPC1_Pick.Dispose();
        MPC2_Pick.Dispose();
        MPC3_Pick.Dispose();
        DMC_Pick.Dispose();
        MPC1_Pick_perp.Dispose();
        MPC2_Pick_perp.Dispose();
        MPC3_Pick_perp.Dispose();
        DMC_Pick_perp.Dispose();

        rngs.Dispose();
        Debug.Log("Check Time t_native: " + ((Time.realtimeSinceStartup - t_native) * 1000f) + " ms");
    }