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()); }
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]; } } }
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); } }
public V7(V6 MPC, int num) { CoordNorm = MPC; Number = num; }
// 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); }
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); } } } } } }
/* // 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); } } } } } }
// 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"); }
// 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"); }
// 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"); }