using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.UI.Extensions; using TMPro; using System.ComponentModel; public class RepositionPNL : MonoBehaviour { public static void StartPNL(string Oname, GameObject selectedOBJ){ SaveXML.BuildWallsData_NonClosedButLoopLastToFirst(); Get.o2("Canvas", "PanelPosition").SetActive(true); string OName=Oname.Split('_')[0]; Get.o3("PanelPosition", "Texting", "Title").GetComponent().text = TRANS.This("T_"+OName); bool TF = GetfloorTF(OName);//set floor cote Get.o2("PanelPosition", "FloorCote").SetActive(TF); Get.o2("PanelPosition", "F").SetActive(TF); Get.o2("PanelPosition", "DepthCote").SetActive(false); Get.o2("PanelPosition", "B").SetActive(false); float w;// =DOIT.CSn(Get.o1("mW").GetComponent().text); float h;// =DOIT.CSn(Get.o1("mH").GetComponent().text); float d = getobjectDepth(OName);;//=DOIT.CSn(Get.o1("mD").GetComponent().text); int On=int.Parse(Oname.Split('_')[1]); if (selectedOBJ != null) CheckWallHit(selectedOBJ,"POSITIONING"); // Pas d'arrondi ici : Mathf.Floor faisait perdre jusqu'a 1" par axe sur la cote affichee. float dx = selectedOBJ != null ? getdx(selectedOBJ) : 0; float dz = selectedOBJ != null ? getdz(selectedOBJ) : 0; int Wallnum=0; float xf; float zf; if(_G.WallSELECTED!="floor"){ Wallnum=int.Parse(_G.WallSELECTED.Replace("w","")); xf=DOIT.xfzf("x",Wallnum);if(Mathf.Abs(xf) < 0.1)xf=0; zf=DOIT.xfzf("z",Wallnum);if(Mathf.Abs(zf) < 0.1)zf=0; } float ff=GetfloorFromFloorDistancce(OName); float FR=0; float FL=0; float FB; int WallPointNext=Wallnum+1; if(WallPointNext>_G.NW){WallPointNext=1;} if(OName=="HOOD")ff=60; Positioning.ObjectName = OName; Get.o2("PanelPosition/INPUTS" ,"D").SetActive(true); // SetImage fixe l'image ET les dimensions par defaut affichees dans W/H. On l'appelle une // seule fois, ici, pour que les cotes L/R soient calculees avec la largeur reellement // affichee (et reprise par ADDOBJECT). Avant, un PATIO calculait avec getobjectWide=36 // alors que le panneau affichait 48 : les cotes etaient fausses de 12". Vector2 defaultSize = SetImage(OName); if(_G.OBJs[On] == null){ //_G.OBJs[On] = new string[100]; w=defaultSize.x; h=defaultSize.y; d=getobjectDepth(OName); } else{ w=DOIT.CSn(_G.OBJs[On][6]); h=DOIT.CSn(_G.OBJs[On][7]); dx=DOIT.CSn(_G.OBJs[On][15]); dz=DOIT.CSn(_G.OBJs[On][17]); ff=_G.HEIGHT/2+DOIT.CSn(_G.OBJs[On][16])-DOIT.CSn(_G.OBJs[On][7])/2; } if(_G.WallSELECTED!="floor"){ float WallWide = _G.WallsWidth[Wallnum-1]; Get.o4("Canvas", "PanelPosition", "Texting", "dimensions").GetComponent().text = TRANS.This("WallWide")+" = " + DOIT.CNs(WallWide); Vector2 ObjectPosition = new(dx,dz); Vector2 WallPositionStart = _G.WallPoints2D[Wallnum-1]/2; // Meme direction que ADDOBJECT : du debut du mur vers son centre. Vector2 WallDirection = (_G.WallsPointCenter[Wallnum-1]/2 - WallPositionStart).normalized; // Projection sur l'axe du mur. Une distance directe (Vector2.Distance) ajoutait l'ecart // perpendiculaire au mur (epaisseur d/2, drag approximatif) a la cote gauche. FL=Vector2.Dot(ObjectPosition-WallPositionStart, WallDirection)-w*0.5f; FL=Mathf.Clamp(FL, 0f, Mathf.Max(0f, WallWide-w));// l'objet reste dans le mur FR=WallWide-w-FL; } if(_G.WallSELECTED=="floor"){ Get.o2("PanelPosition", "DepthCote").SetActive(true); Get.o2("PanelPosition", "B").SetActive(true); Get.o2("PanelPosition", "FloorCote").SetActive(true); Get.o2("PanelPosition", "F").SetActive(true); // dx/dz sont absolus (espace scene) : on les ramene au centre de la piece, qui n'est // pas forcement l'origine quand la piece a ete dessinee. Vector2 roomCenter = RoomRectScene().center; FR=(_G.WIDE-w)/2f-(dx-roomCenter.x); FL=(_G.WIDE-w)-FR; FB=(_G.DEPTH-d)/2f-(dz-roomCenter.y); ff=(_G.DEPTH-d)-FB; Get.o4("Canvas", "PanelPosition", "Texting", "dimensions").GetComponent().text = TRANS.This("F_Overall")+" " + DOIT.CNs(_G.WIDE)+" x " + DOIT.CNs(_G.DEPTH); Get.o1("mB").GetComponent().text=DOIT.CNs(FB); Get.o1("mF").GetComponent().text=DOIT.CNs(ff); } GameObject WALL = Get.o2("PanelPosition","WALL"); GameObject INPUTS = Get.o2("PanelPosition","INPUTS"); if(WALL != null){ Transform goR = WALL.transform.Find("R"); if(goR != null) goR.Find("mR").GetComponent().text = DOIT.CNs(FR); Transform goL = WALL.transform.Find("L"); if(goL != null) goL.Find("mL").GetComponent().text = DOIT.CNs(FL); } if(TF) Get.o1("mF").GetComponent().text = DOIT.CNs(ff); if(INPUTS != null){ Transform goW = INPUTS.transform.Find("W"); if(goW != null) goW.Find("mW").GetComponent().text = DOIT.CNs(w); Transform goH = INPUTS.transform.Find("H"); if(goH != null) goH.Find("mH").GetComponent().text = DOIT.CNs(h); Transform goD = INPUTS.transform.Find("D"); if(goD != null) goD.Find("mD").GetComponent().text = DOIT.CNs(d); } // La retombee a une vraie profondeur (24" par defaut) qu'on doit pouvoir ajuster, // au meme titre que l'epaisseur d'un mur pour une porte ou une fenetre. bool showDepth = getName(OName) is "DOOR" or "WINDOW" or "OPEN" or "BULKHEAD"; Get.o2("PanelPosition/INPUTS" ,"D").SetActive(showDepth); _G.SELECTED=Oname; //ADDOBJECT.newObstacle(); } public static void NewPositionOnWall(string Measure,float DeltaValue) { int Wallnum=int.Parse(_G.WallSELECTED.Replace("w","")); float WallWide = _G.WallsWidth[Wallnum-1]; TMP_Text TR=Get.o2("PanelPosition/WALL/R","mR").GetComponent(); TMP_Text TL=Get.o2("PanelPosition/WALL/L","mL").GetComponent(); TMP_Text TW=Get.o2("PanelPosition/INPUTS/W","mW").GetComponent(); float NewWideOnject= DOIT.ConvertStringToNumber(TW.text); float NewMeasureLeft= DOIT.ConvertStringToNumber(TL.text); float NewMeasureRight= DOIT.ConvertStringToNumber(TR.text); if (Measure == "mL") { TR.text=(WallWide-NewWideOnject-NewMeasureLeft).ToString(); } if (Measure == "mR") { TL.text=(WallWide-NewWideOnject-NewMeasureRight).ToString(); } if (Measure == "mW") { TR.text=(NewMeasureRight-DeltaValue*0.5f).ToString(); TL.text=(NewMeasureLeft-DeltaValue*0.5f).ToString(); } print("DeltaValue==="+DeltaValue+" WallWide===="+WallWide); } //================GET================================================ // Le "Plan" du panneau courant. GameObject.Find n'atteint que les objets actifs : // on prend d'abord le panneau affiche (_G.PNL), les autres ne servent que de secours. static Transform GetPlanTransform() { GameObject plan = Get.o2(_G.PNL, "Plan"); if (plan == null) plan = Get.o2("POSITIONING", "Plan"); if (plan == null) plan = Get.o2("OBSTACLES", "Plan"); return plan != null ? plan.transform : null; } // Position d'un objet glisse (enfant de OBSTACLELIST) convertie en espace scene. // Le contenu du plan est en unites WallPoints2D et l'espace scene (px/pz de _G.OBJs) en vaut // la moitie. SetPlan.FitPlan applique une echelle ET un decalage // (anchoredPosition = -centreContenu * echelle) parce que la piece dessinee n'est pas centree // sur l'origine : il faut donc passer par InverseTransformPoint. Diviser seulement par // l'echelle decalait l'objet du centre de la piece (cotes hors du mur, valeurs negatives). public static Vector2 ScenePosition(GameObject O) { Transform plan = GetPlanTransform(); if (O == null || plan == null) return Vector2.zero; Vector3 local = plan.InverseTransformPoint(O.transform.position); return new Vector2(local.x, local.y) * 0.5f; } // Boite englobante de la piece en espace scene (= WallPoints2D / 2). public static Rect RoomRectScene() { if (_G.WallPoints2D == null || _G.WallPoints2D.Count == 0) return Rect.MinMaxRect(-_G.WIDE*0.5f, -_G.DEPTH*0.5f, _G.WIDE*0.5f, _G.DEPTH*0.5f); Vector2 min = _G.WallPoints2D[0]*0.5f; Vector2 max = min; foreach (Vector2 p in _G.WallPoints2D) { Vector2 s = p*0.5f; min = Vector2.Min(min, s); max = Vector2.Max(max, s); } return Rect.MinMaxRect(min.x, min.y, max.x, max.y); } public static float getdx(GameObject O){ return ScenePosition(O).x; } public static float getdz(GameObject O){ return ScenePosition(O).y; } public static float getobjectWide(string N){ float W=0; switch(N){ case "WINDOW":W=36;break; case "FENÊTRE":W=36;break; case "DOOR":W=32;break; case "PORTE":W=32;break; case "STOVE":W=30;break; case "CUISINIÈRE":W=30;break; case "FRIDGE":W=30;break; case "REFRIGÉRATEUR":W=30;break; case "DISH":W=24;break; case "PATIO":W=36;break; case "WASHER":W=24;break; case "DRYER":W=24;break; case "OPENING":W=48;break; case "HOOD":W=30;break; case "GAZ":W=12;break; case "PLUMBING":W=12;break; case "BLOC":W=24;break; } return W; } public static float getobjectHight(string N){ float H=0; switch(N){ case "WINDOW":H=42;break; case "FENÊTRE":H=42;break; case "DOOR":H=84;break; case "PORTE":H=84;break; case "STOVE":H=36;break; case "CUISINIÈRE":H=36;break; case "FRIDGE":H=68;break; case "REFRIGÉRATEUR":H=68;break; case "DISH":H=36;break; case "PATIO":H=84;break; case "WASHER":H=36;break; case "DRYER":H=36;break; case "OPENING":H=84;break; case "HOOD":H=36;break; case "GAZ":H=12;break; case "PLUMBING":H=12;break; case "BLOC":H=36;break; } return H; } public static float getobjectDepth(string N){ print("N==="+N); float d=2; if(Get.o1("mD")!=null){d=DOIT.CSn(Get.o1("mD").GetComponent().text);} switch(N){ case "WINDOW":d=10f;break; case "DOOR":d=6f;break; case "OPENING":d=6f;break; case "STOVE":d=24f;break; case "FRIDGE":d=24f;break; case "DISH":d=24f;break; case "PATIO":d=10f;break; case "WASHER":d=24f;break; case "DRYER":d=24f;break; case "GAZ":d=2f;break; case "PLUMBING":d=2f;break; case "BLOC":d=24f;break; case "BULKHEAD":d=24f;break;// retombee : profondeur du caisson sous le plafond } return d; } public static bool GetfloorTF(string N){ bool TF=false; switch(N){ case "WINDOW":TF=true;break; case "FENÊTRE":TF=true;break; case "HOOD":TF=true;break; case "VENTILLATEUR":TF=true;break; case "GAZ":TF=true;break; case "PLUMBING":TF=true;break; case "PLOMBERIE":TF=true;break; case "BLOC":TF=true;break; } return TF; } public static float GetfloorFromFloorDistancce(string N){ //bool TF=false; return N switch { "WINDOW" => 36, "FENÊTRE" => 36, "HOOD" => 60, "VENTILLATEUR" => 60, "GAZ" => 18, "PLUMBING" => 18, "PLOMBERIE" => 18, "BLOC" => 18, _ => 0, }; } // Retourne les dimensions (largeur, hauteur) par defaut appliquees a l'objet. public static Vector2 SetImage(string ObjectName){ GameObject ImageObject= Get.o2("Canvas/PanelPosition/WALL","ImageObject"); GameObject WALL= Get.o2("Canvas/PanelPosition","WALL"); bool isBTN_Select=true; bool isMeasureSide=true; string path="Bloc/BLOC101"; float H=24; float W=24; //float dy=18f; RectTransform Or=ImageObject.GetComponent(); float ceiling=_G.HEIGHT*0.5f; float floor =-_G.HEIGHT*0.5f; switch (ObjectName) { case "WINDOW": path="Windows/WIND101";H=42;W=30; Or.sizeDelta = new Vector2(W, H); Or.anchoredPosition = new Vector2(Or.anchoredPosition.x, 0); break; case "PATIO": path="Patio/PATI101";H=82;W=48; Or.sizeDelta = new Vector2(W, H); Or.anchoredPosition = new Vector2( Or.anchoredPosition.x, floor+H*0.5f); break; case "DOOR": path="Doors/DOOS101";H=82;W=32; Or.sizeDelta = new Vector2(W, H); Or.anchoredPosition = new Vector2( Or.anchoredPosition.x, floor+H*0.5f); break; case "FRIDGE": if(_G.WallSELECTED!="floor"){path="Fridge/FRID101";H=70; W=32;} Or.sizeDelta = new Vector2(W, H); Or.anchoredPosition = new Vector2( Or.anchoredPosition.x, floor+H*0.5f); break; case "STOVE": if(_G.WallSELECTED!="floor"){path="Stove/STOV101";H=44;W=30;} Or.sizeDelta = new Vector2(30, H); Or.anchoredPosition = new Vector2( Or.anchoredPosition.x, floor+H*0.5f); break; case "DISH": if(_G.WallSELECTED!="floor"){path="Dishwasher/DISW101";H=36;W=24;} Or.sizeDelta = new Vector2(W, H); Or.anchoredPosition = new Vector2( Or.anchoredPosition.x, floor+H*0.5f); break; case "WASHER": if(_G.WallSELECTED!="floor"){path="WD/WADR101";H=36;W=24;} Or.sizeDelta = new Vector2(W, H); Or.anchoredPosition = new Vector2( Or.anchoredPosition.x, floor+H*0.5f); break; case "DRYER": if(_G.WallSELECTED!="floor"){path="WD/WADR102";H=36;W=24;} Or.sizeDelta = new Vector2(W, H); Or.anchoredPosition = new Vector2( Or.anchoredPosition.x, floor+H*0.5f); break; case "HOOD": if(_G.WallSELECTED!="floor"){path="HoodFan/HOOW101";H=60;W=30;} Or.sizeDelta = new Vector2(W, H); Or.anchoredPosition = new Vector2( Or.anchoredPosition.x, ceiling -H*0.5f); //Get.o3("Canvas", "PanelSelection", "HOOD").gameObject.SetActive(true); break; case "OPENING": path="Openning/OPEN101";H=82;W=48; Or.sizeDelta = new Vector2(W, H); Or.anchoredPosition = new Vector2( Or.anchoredPosition.x, floor+H*0.5f); break; case "GAZ": if(_G.WallSELECTED!="floor"){path="Gaz/BLOC118";H=12;W=12;} Or.sizeDelta = new Vector2(W, H); Or.anchoredPosition = new Vector2( Or.anchoredPosition.x, 0); isBTN_Select=false; break; case "PLUMBING": if(_G.WallSELECTED!="floor"){path="Plumbing/BLOC119";H=12;W=12;} Or.sizeDelta = new Vector2(W, H); Or.anchoredPosition = new Vector2( Or.anchoredPosition.x, 0); isBTN_Select=false; break; case "BLOC": if(_G.WallSELECTED!="floor"){path="Bloc/BLOC101";H=24;W=24;} Or.sizeDelta = new Vector2(W, H); Or.anchoredPosition = new Vector2( Or.anchoredPosition.x, 0); isBTN_Select=false; break; case "BULKHEAD": path="Bulkhead/BLOC117";H=12;W=192; Or.sizeDelta = new Vector2(W, H); Or.anchoredPosition = new Vector2( Or.anchoredPosition.x, ceiling-H*0.5f); isBTN_Select=false; isMeasureSide=false; break; } Get.o2("PanelPosition/INPUTS/W","mW").GetComponent().text=DOIT.CNs(W); Get.o2("PanelPosition/INPUTS/H","mH").GetComponent().text=DOIT.CNs(H); ImageObject.GetComponent().sprite = Resources.Load("Images/Icons/"+path) as Sprite; Set.alpha(ImageObject.transform.Find("BTN_Select").gameObject,isBTN_Select); ImageObject.transform.Find("BTN_Select").transform.localPosition = new Vector3(W*0.5f, H*0.5f, 0); WALL.transform.Find("45R").transform.localPosition = new Vector3(W*0.5f, 0, 0); WALL.transform.Find("45L").transform.localPosition = new Vector3(-W*0.5f, 0, 0); WALL.transform.Find("45R").gameObject.SetActive(isMeasureSide); WALL.transform.Find("45L").gameObject.SetActive(isMeasureSide); WALL.transform.Find("lineH").gameObject.SetActive(isMeasureSide); WALL.transform.Find("R").gameObject.SetActive(isMeasureSide); WALL.transform.Find("L").gameObject.SetActive(isMeasureSide); return new Vector2(W, H); } public static void DeleteSelected() { if (string.IsNullOrEmpty(_G.SELECTED)) return; int nO = int.Parse(_G.SELECTED.Split('_')[1]); // Effacer les données if (_G.OBJs[nO] != null) _G.OBJs[nO][0] = "null"; // Supprimer l'objet 3D de la scène GameObject sceneObj = GameObject.Find(_G.SELECTED); if (sceneObj != null) DestroyImmediate(sceneObj); // Supprimer le toggle dans OBSTACLELIST GameObject listParent = Get.o2("Canvas", "OBSTACLELIST"); if (listParent != null) { Transform item = listParent.transform.Find(_G.SELECTED); if (item != null) DestroyImmediate(item.gameObject); } _G.SELECTED = ""; DELETE.Refresh(); Get.o2("Canvas", "PanelPosition").SetActive(false); if (_G.PNL == "WALLCAB") { SetPlan.Rooms(); Measure.RebuildWALLCABPlan(); } } public static void CheckWallHit(GameObject selectedOBJ,string pnl) { _G.WallSELECTED = "floor"; var selRT = selectedOBJ.GetComponent(); if (!selRT) return; Bounds selB = RTBounds(selRT); int setNW = (!_G.ROOMCLOSE) ? 1 : 0; for (int i = 1; i < _G.NW + 1 - setNW; i++) { var wall = Get.o3(pnl, "Plan", "w" + i); if (!wall) continue; var wallRT = wall.GetComponent(); var img = wall.GetComponent(); if (!wallRT || !img) continue; bool hit = selB.Intersects(RTBounds(wallRT)); img.color = hit ? Color.green : Color.black; if (hit) _G.WallSELECTED = "w" + i; } // //print("----checkWallHi----"); // _G.WallSELECTED="floor"; // int setNW =0; // if(!_G.ROOMCLOSE){setNW =1;} // for (int i = 1; i < _G.NW+1-setNW ; i++) // { // if( CollisionDetection.IsTouching( selectedOBJ, Get.o3(pnl,"Plan","w"+i) )){ // //print("-----------------------------ok doit---------------"+" w"+i); // Get.o3(pnl,"Plan","w"+i).transform.GetComponent().color=Color.green; // _G.WallSELECTED="w"+i.ToString(); // } // else{ Get.o3(pnl,"Plan","w"+i).transform.GetComponent().color=Color.black; } // } } static Bounds RTBounds(RectTransform rt) { Vector3[] c = new Vector3[4]; rt.GetWorldCorners(c); var b = new Bounds(c[0], Vector3.zero); for (int i = 1; i < 4; i++) b.Encapsulate(c[i]); return b; } public static string getName(string N){ string Name=N; switch(Name){ case "FENÊTRE":N="WINDOW";break; case "PORTE":N="DOOR";break; case "CUISINIÈRE":N="STOVE";break; case "REFRIGÉRATEUR":N="FRIDGE";break; case "DISHWASHER":N="DISH";break; case "LAVE VAILSELLE":N="DISH";break; case "LAVEUSE":N="WASHER";break; case "SÈCHEUSE":N="DRYER";break; case "OUVERTURE":N="OPENING";break; case "VENTILATEUR":N="HOOD";break; case "FAN":N="HOOD";break; } return N; } }