using UnityEngine.UI; using System.Collections.Generic; using UnityEngine; using System.Globalization; using UnityEngine.Animations; using System; using System.Security.Cryptography; using System.Drawing; public class ConstructOGEE : MonoBehaviour { static float hO = 3;//Height of Ogee static float csOL = 0;//Ogee Left offset static float csOR = 0;//Ogee right offset static float csOF = 0;//Ogee offset top when angle static int ADN; public static void OGEE(List> objectList) { DOIT.DELETEAllChild("OgeeContainer"); foreach (List list in objectList) { foreach (GameObject Object in list) { DOIT.DELETEAllChildName(Object.transform, new List() { "0_45", "45_0", "0_0", "45_45", "0_22", "22_0" }); } List TARLIST = list; List SELLIST = TARLIST; foreach (GameObject TAR in TARLIST) { ADN = Get.GetObjectIndex(TAR.name); if (_G.OBJs[ADN][64].Split("?")[0] != "NONE") { _G.OBJs[ADN][70] = "Om1,0,Om3,Om4"; string[] OC = _G.OBJs[ADN][70].Split(","[0]); //Get All points & verify if touching foreach (GameObject SEL in SELLIST) { if (SEL.name != TAR.name) { Vector3 Tp1 = RepositionPoint(TAR, "1"); Vector3 Tp4 = RepositionPoint(TAR, "4"); Vector3 Tp2 = RepositionPoint(TAR, "2"); Vector3 Tp3 = RepositionPoint(TAR, "3"); Vector3 Sp1 = RepositionPoint(SEL, "1"); Vector3 Sp4 = RepositionPoint(SEL, "4"); Vector3 Sp2 = RepositionPoint(SEL, "2"); Vector3 Sp3 = RepositionPoint(SEL, "3"); if (Touching(Tp1, Sp3)) { OC[0] = "0"; } if (Touching(Tp1, Sp4)) { OC[0] = "0"; } if (Touching(Tp2, Sp4)) { OC[0] = "0"; } if (Touching(Tp3, Sp1)) { OC[2] = "0"; } if (Touching(Tp4, Sp1)) { OC[2] = "0"; } if (Touching(Tp4, Sp2)) { OC[2] = "0"; } } } _G.OBJs[ADN][70] = OC[0] + "," + OC[1] + "," + OC[2] + "," + OC[3]; } if (_G.OBJs[ADN][64].Split("?")[0] != "NONE") { AddOgee(TAR); } } } } private static bool Touching(Vector3 V1, Vector3 V2) { float dist = Vector3.Distance(V1, V2); if (dist < 2) return true; return false; } private static Vector3 RepositionPoint(GameObject Point, string Number) { // string direction1 = "dir1"; // string direction2 = "dir2"; // float offset = 1; // Transform point = obj.transform.Find("PO" + PointName); // if (point == null) // { // Debug.LogError("PO" + PointName + " not found"); // return Vector3.zero; // } // Transform t1 = obj.transform.Find("PO" + direction1); // Transform t2 = obj.transform.Find("PO" + direction2); // if (t1 == null || t2 == null) // { // Debug.LogError("PO" + direction1 + " or PO" + direction2 + " not found"); // return Vector3.zero; // } // // CALCUL en local // Vector3 localP1 = obj.transform.InverseTransformPoint(t1.position); // Vector3 localP2 = obj.transform.InverseTransformPoint(t2.position); // Vector3 direction = (localP2 - localP1).normalized; // Vector3 localPoint = obj.transform.InverseTransformPoint(point.position); // Vector3 newLocalPosition = localPoint + direction * offset; // return obj.transform.TransformPoint(newLocalPosition); int nO = Get.GetObjectIndex(Point.name); Vector3 StartPosition = Point.transform.Find("PO" + Number).position; float flw = 0;//Filler wide float frw = 0;//Filler height string[] C = _G.OBJs[nO]; //print("C[50]===="+C[50]);//F1_1?1?90?3 if (C[50].IndexOf("NONE") == -1) { flw = DOIT.ConvertStringToNumber(C[50].Split("?")[3]); } if (C[51].IndexOf("NONE") == -1) { frw = DOIT.ConvertStringToNumber(C[51].Split("?")[3]); } Vector3 EP = StartPosition;//EndPosition Vector3 dir = GetDirection(Point, "4", "1"); float OSP = 0.625f * 0.5f + 0.25f;//OffSet for fascia Over if (C[4] == "W1" || C[4] == "T1") { if (flw != 0 && Number == "1") EP -= flw * dir; if (frw != 0 && Number == "4") EP += frw * dir; Vector3 dir12 = GetDirection(Point, "1", "2") * OSP; Vector3 dir14 = GetDirection(Point, "1", "4") * OSP; ///Offset if (Number == "1") EP += dir14 + dir12; if (Number == "2") EP += dir14; if (Number == "3") EP += -dir14; if (Number == "4") EP += -dir14 + dir12; } if (Get.Bool(C[4], "W2_W9_W3_W10")) { Vector3 dir45 = GetDirection(Point, "4", "5"); Vector3 dir15 = GetDirection(Point, "1", "5"); if (flw == 0 && Number == "1") EP += OSP * dir45 + OSP * dir15; if (frw == 0 && Number == "4") EP += OSP * dir45 + OSP * dir15; if (Number == "2") EP += OSP * dir15; if (Number == "3") EP += OSP * dir45; if (flw != 0 && Number == "1") EP += (flw + OSP * 0.5f) * dir15 + OSP * dir45; if (frw != 0 && Number == "4") EP += (frw + OSP * 0.5f) * dir45 + OSP * dir15; if (Number == "5") EP += OSP * dir45 + OSP * dir15; } if (Get.Bool(C[4], "W4_W19_W5_W20")) { Vector3 dir12 = GetDirection(Point, "1", "2"); Vector3 dir43 = GetDirection(Point, "4", "3"); if (Number == "1") EP += OSP * dir12 + OSP * dir43; if (Number == "4") EP += OSP * dir12 + OSP * dir43; if (frw == 0 && Number == "2") EP += OSP * dir43; if (frw == 0 && Number == "3") EP += OSP * dir12; if (flw != 0 && Number == "2") EP = Point.transform.Find("PO1").position + (flw + OSP * 0.5f) * dir43 + OSP * dir12; if (frw != 0 && Number == "3") EP = Point.transform.Find("PO4").position + (frw + OSP * 0.5f) * dir12 + OSP * dir43; } if (Get.Bool(C[4], "W6_W11_W26_W7_W12_W27")) { Vector3 dir43 = GetDirection(Point, "4", "3"); Vector3 dir12 = GetDirection(Point, "1", "2"); if (Number == "1") EP += OSP * dir12 + OSP * dir43; if (Number == "4") EP += OSP * dir12 + OSP * dir43; if (Number == "2") EP += OSP * dir43; if (Number == "3") EP += OSP * dir12; if (flw != 0 && Number == "2") EP += -flw * dir12; if (frw != 0 && Number == "3") EP += -frw * dir43; } float OggeHeight = DOIT.ConvertStringToNumber(C[64].Split('?')[^1]); float FasciaHeight = DOIT.ConvertStringToNumber(C[66].Split('?')[^1]); float OY = FasciaHeight - OggeHeight; if (OY < 0) OY = 0; EP = new(EP.x, EP.y + OY, EP.z); return EP; //EP = Point.transform.InverseTransformPoint(EP); //return Point.transform.InverseTransformPoint(StartPosition); //return Point.transform.TransformPoint(Point.transform.InverseTransformPoint(EP)); //return StartPosition.transform.TransformPoint(Point.transform.InverseTransformPoint(EP)); } public static Vector3 GetDirection(GameObject Point, string nP1, string np2) { Vector3 p1 = Point.transform.Find("PO" + nP1).position; Vector3 p2 = Point.transform.Find("PO" + np2).position; return (p1 - p2).normalized; } private static void AddOgee(GameObject TAR) { ADN = Get.GetObjectIndex(TAR.name); string[] C = _G.OBJs[ADN]; if (C[64].Split('?').Length == 1) C[64] = "NONE" + "?1" + "?6"; string[] OC = C[70].Split(','); string[] code = _G.OBJs[ADN][64].Split('?'); hO = DOIT.ConvertStringToNumber(code[^1]); string Model = C[4]; string ModelShape = UIT.Value(Library.Molding, code[0], Header.Model); csOF = 0; if (ModelShape == "2" || ModelShape == "3" || ModelShape == "4") { csOF = 3 * 0.707f; } if (code[0] != "NONE" && CheckOver(TAR) && hO != 0) { Vector3 PO1 = RepositionPoint(TAR, "1"); Vector3 PO2 = RepositionPoint(TAR, "2"); Vector3 PO3 = RepositionPoint(TAR, "3"); Vector3 PO4 = RepositionPoint(TAR, "4"); Vector3 PO = Vector3.zero; if (C[50] != "NONE") OC[0] = "0"; if (C[51] != "NONE") OC[2] = "0"; if (C[4] == "W1" || C[4] == "T1") { //SIDES if (OC[0] != "0") { DrawFace(TAR, "0_45", PO2, PO1, PO, PO4, ADN); } if (OC[2] != "0") { DrawFace(TAR, "45_0", PO4, PO3, PO1, PO, ADN); } //FRONT if (C[50] != "NONE" && C[51] == "NONE") { DrawFace(TAR, "0_45", PO1, PO4, PO, PO3, ADN); } else if (C[51] != "NONE" && C[50] == "NONE") { DrawFace(TAR, "45_0", PO1, PO4, PO, PO3, ADN); } else if (C[51] != "NONE" && C[50] != "NONE") { DrawFace(TAR, "0_0", PO1, PO4, PO, PO, ADN); } else if (C[50] == "NONE" && C[51] == "NONE") { DrawFace(TAR, "45_45", PO1, PO4, PO2, PO3, ADN); } } if (new List { "W2", "W9" }.Contains(Model)) { Vector3 PO5 = RepositionPoint(TAR, "5"); if (OC[0] != "0") { DrawFace(TAR, "0_22", PO2, PO1, PO, PO5, ADN); } if (OC[2] != "0") { DrawFace(TAR, "22_0", PO4, PO3, PO5, PO, ADN); } if (C[50] != "NONE" && C[51] == "NONE") { DrawFace(TAR, "Om41", PO5, PO4, PO1, PO3, ADN); DrawFace(TAR, "Om41", PO1, PO5, PO2, PO4, ADN); } else if (C[51] != "NONE" && C[50] == "NONE") { DrawFace(TAR, "45_0", PO5, PO4, PO1, PO, ADN); DrawFace(TAR, "45_0", PO1, PO5, PO2, PO4, ADN); } else if (C[51] != "NONE" && C[50] != "NONE") { DrawFace(TAR, "0_0", PO5, PO4, PO, PO, ADN); DrawFace(TAR, "0_0", PO1, PO5, PO, PO, ADN); } else if (C[50] == "NONE" && C[51] == "NONE") { DrawFace(TAR, "45_45", PO5, PO4, PO2, PO3, ADN); DrawFace(TAR, "45_45", PO1, PO5, PO2, PO3, ADN); } } if (new List { "W3", "W10" }.Contains(Model)) { Vector3 PO5 = RepositionPoint(TAR, "5"); if (OC[0] != "0") { DrawFace(TAR, "0_22", PO2, PO1, PO, PO5, ADN); } if (OC[2] != "0") { DrawFace(TAR, "22_0", PO4, PO3, PO5, PO, ADN); } if (C[50] != "NONE" && C[51] == "NONE") { DrawFace(TAR, "Om41", PO5, PO4, PO1, PO3, ADN); DrawFace(TAR, "Om41", PO1, PO5, PO2, PO4, ADN); } else if (C[51] != "NONE" && C[50] == "NONE") { DrawFace(TAR, "45_0", PO5, PO4, PO1, PO, ADN); DrawFace(TAR, "45_0", PO1, PO5, PO2, PO4, ADN); } else if (C[51] != "NONE" && C[50] != "NONE") { DrawFace(TAR, "0_0", PO5, PO4, PO, PO, ADN); DrawFace(TAR, "0_0", PO1, PO5, PO, PO, ADN); } else if (C[50] == "NONE" && C[51] == "NONE") { DrawFace(TAR, "45_45", PO5, PO4, PO2, PO3, ADN); DrawFace(TAR, "45_45", PO1, PO5, PO2, PO3, ADN); } } if (new List { "W4", "W5", "W19", "W20" }.Contains(Model)) { //SIDE if (OC[0] != "0") { DrawFace(TAR, "0_22", PO2, PO1, PO, PO4, ADN); } if (OC[2] != "0") { DrawFace(TAR, "22_0", PO4, PO3, PO1, PO, ADN); } //FRONT if (C[50] != "NONE" && C[51] == "NONE") { DrawFace(TAR, "0_22", PO1, PO4, PO, PO3, ADN); } if (C[51] != "NONE" && C[50] == "NONE") { DrawFace(TAR, "22_0", PO1, PO4, PO, PO3, ADN); } if (C[51] != "NONE" && C[50] != "NONE") { DrawFace(TAR, "0_0", PO1, PO4, PO, PO, ADN); } if (C[50] == "NONE" && C[51] == "NONE") { DrawFace(TAR, "22_22", PO1, PO4, PO2, PO3, ADN); } } // if (new List{"W6","W7","W11","W12","W26","W27"}.Contains(Model)) // { // DrawFace(TAR,"Ogee1",PO2, PO1,ADN); // DrawFace(TAR,"Ogee2",PO4, PO3,ADN); // DrawFace(TAR,"Ogee4",PO4, PO1,ADN); // } } } private static void DrawFace(GameObject TAR, string name, Vector3 P1, Vector3 P4, Vector3 PP, Vector3 PN, int i) { float height = hO; float offset = csOF; // Points du haut Vector3 P2 = new Vector3(P1.x, P1.y + height, P1.z); Vector3 P3 = new Vector3(P4.x, P4.y + height, P4.z); // Directions Vector3 Direction = (P4 - P1).normalized; Vector3 RightDirection = Vector3.Cross(Vector3.up, Direction).normalized; Vector3 PrevDirection = (P1 - PP).normalized; if (PP == Vector3.zero) PrevDirection = Direction; Vector3 NextDirection = (PN - P4).normalized; if (PN == Vector3.zero) NextDirection = -Direction; Vector3 RightPrev = Vector3.Cross(Vector3.up, PrevDirection).normalized; Vector3 RightNext = Vector3.Cross(Vector3.up, NextDirection).normalized; // Décalage des points du haut pour trouver intersection Vector3 NewP2P = P2 + offset * RightPrev; Vector3 NewP2N = P2 + offset * RightDirection; P2 = FindIntersectionPoint(NewP2P, -PrevDirection, NewP2N, Direction); Vector3 NewP3P = P3 + offset * RightDirection; Vector3 NewP3N = P3 + offset * RightNext; P3 = FindIntersectionPoint(NewP3P, Direction, NewP3N, NextDirection); // Appelle CreateOgee avec points en monde CreateOgee(TAR, name, P1, P2, P3, P4, i); } private static void CreateOgee(GameObject TAR, string Name, Vector3 P1, Vector3 P2, Vector3 P3, Vector3 P4, int i) { GameObject s = new(Name); s.transform.SetParent(TAR.transform, false); // garde les coords locales intactes MeshFilter mf = s.AddComponent(); MeshRenderer mr = s.AddComponent(); // Crée un mesh avec les coordonnées monde converties en local par rapport à ce GameObject mf.mesh = CreateMesh(s.transform, P1, P2, P3, P4); string[] ADN = _G.OBJs[i]; string[] split64 = ADN[64].Split("?"); mr.material = UIT_MATERIAL.GetMaterial(split64[1] + "?" + split64[2]); mr.material.SetFloat("_Rotation", 90); mr.material.SetFloat("_Cull", 0); string model = split64[0]; string ModelShadow = UIT.Value(Library.Molding, model, Header.Model); if (ModelShadow.Split('_').Length == 1) ModelShadow = "O_" + ModelShadow; if (ModelShadow != "O_1" && ModelShadow != "O_") { Texture2D T = UnityEngine.Object.Instantiate(Resources.Load("OGEE/" + ModelShadow)); mr.material.SetTexture("_Shadow", T); mr.material.SetFloat("_Relief", 0.8f); } mr.probeAnchor = GameObject.Find("Reflection Probe")?.transform; } private static Mesh CreateMesh(Transform target, Vector3 P1, Vector3 P2, Vector3 P3, Vector3 P4) { // Transforme les points monde en points locaux par rapport à target (le GameObject qui reçoit le mesh) Vector3[] vertices = new Vector3[] { target.InverseTransformPoint(P1), target.InverseTransformPoint(P2), target.InverseTransformPoint(P3), target.InverseTransformPoint(P4), }; Mesh m = new() { vertices = vertices, uv = new Vector2[] { new (0, 0), new (0, 1), new (1, 1), new (1, 0) }, triangles = new int[] { 0, 1, 2, 0, 2, 3 } }; m.RecalculateNormals(); m.RecalculateTangents(); return m; } private static bool CheckOver(GameObject TAR) { int indT = Get.GetObjectIndex(TAR.name); float Tx = DOIT.ConvertStringToNumber(_G.OBJs[indT][15]); float Ty = DOIT.ConvertStringToNumber(_G.OBJs[indT][16]); float Tz = DOIT.ConvertStringToNumber(_G.OBJs[indT][17]); float Th = DOIT.ConvertStringToNumber(_G.OBJs[indT][7]); bool OK = true; List CW = DOLIST.OBJLIST(); foreach (GameObject obj in CW) { if (TAR.name != obj.name) { int indO = Get.GetObjectIndex(obj.name); float Ox = DOIT.ConvertStringToNumber(_G.OBJs[indO][15]); float Oy = DOIT.ConvertStringToNumber(_G.OBJs[indO][16]); float Oz = DOIT.ConvertStringToNumber(_G.OBJs[indO][17]); float Oh = DOIT.ConvertStringToNumber(_G.OBJs[indO][7]); float Dx = Mathf.Abs(Ox - Tx); float Dy = Mathf.Abs(Oy - Ty); float Dz = Mathf.Abs(Oz - Tz); float Dh = (Th / 2) + (Oh / 2); if (Dx <= 10 && Dz <= 10 && Dy <= Dh + 6 && CHECKINSIDE(TAR, obj) == false && Oy > Ty) { OK = false; } } } return OK; } public static bool CHECKINSIDE(GameObject T, GameObject O) { bool BI = false; Vector3 TV = T.transform.position; Vector3 OV = O.transform.position; float disX = Mathf.Abs(TV.x - OV.x); float disY = Mathf.Abs(TV.y - OV.y); float disZ = Mathf.Abs(TV.z - OV.z); Vector3 OB = T.GetComponent().bounds.size; if (disX < OB.x / 2 && disZ < OB.z / 2 && disY < OB.y / 2) { BI = true; } return BI; } public static Vector3 GetRightDirection3D(Vector3 normalizedVector, Vector3 up = default) { if (up == default) up = Vector3.up; // Default up vector is (0, 1, 0) // Use the cross product to calculate the right direction return Vector3.Cross(up, normalizedVector).normalized; } public static float FindSignedAngle(Vector3 pointA, Vector3 pointB, Vector3 direction, Vector3 rightDirection) { // Calculate the vector from A to B Vector3 AB = (pointB - pointA).normalized; // Project AB onto the direction and right direction to get the components float forwardDot = Vector3.Dot(AB, direction); float rightDot = Vector3.Dot(AB, rightDirection); // Calculate the angle in degrees using atan2 float angle = Mathf.Atan2(rightDot, forwardDot) * Mathf.Rad2Deg; return angle; // Signed angle } public static float FindAngle(Vector3 dir1, Vector3 dir2) { // Ensure both vectors are normalized dir1.Normalize(); dir2.Normalize(); // Calculate the dot product float dot = Vector3.Dot(dir1, dir2); // Clamp the dot product to avoid numerical errors dot = Mathf.Clamp(dot, -1f, 1f); // Calculate the angle in degrees float angle = Mathf.Acos(dot) * Mathf.Rad2Deg; return angle; } public static Vector3 FindIntersectionPoint(Vector3 p1, Vector3 d1, Vector3 p2, Vector3 d2) { // Ensure the direction vectors are normalized d1.Normalize(); d2.Normalize(); // Calculate the cross product of the direction vectors Vector3 cross = Vector3.Cross(d1, d2); // If the cross product is nearly zero, the lines are parallel if (cross.sqrMagnitude < 1e-6f) { return p1; } // Calculate the closest points on the two lines Vector3 diff = p2 - p1; float a = Vector3.Dot(diff, Vector3.Cross(d2, cross)) / cross.sqrMagnitude; float b = Vector3.Dot(diff, Vector3.Cross(d1, cross)) / cross.sqrMagnitude; // Calculate the closest points Vector3 closestPoint1 = p1 + d1 * a; Vector3 closestPoint2 = p2 + d2 * b; // Check if the closest points are close enough to consider them as intersecting if (Vector3.Distance(closestPoint1, closestPoint2) < 1e-3f) { return (closestPoint1 + closestPoint2) / 2f; } return p1; } private static Vector3 RotateAroundPivot(Vector3 point, Vector3 pivot, Quaternion rotation) { return pivot + rotation * (point - pivot); } public static Vector3 ToLocal(Transform parent, Vector3 worldPosition) { return parent.InverseTransformPoint(worldPosition); } }