///<summary> /// Update the Sensor attributes with given SApiObject. ///</summary> ///<param name="_src">The SApiObject used to update attributes</param> public override void UpdateFromSApiObject(SApiObject _src) { name = _src.name; id = _src.id; parentId = _src.parentId; category = _src.category; domain = _src.domain; description = _src.description; attributes = _src.attributes; }
///<summary> /// Parse a nested SApiObject and add each item to a given list. ///</summary> ///<param name="_list">The list of objects to complete</param> ///<param name="_src">The head of nested SApiObjects</param> public static void ParseNestedObjects(List <SApiObject> _list, SApiObject _src) { _list.Add(_src); if (_src.children != null) { foreach (SApiObject obj in _src.children) { ParseNestedObjects(_list, obj); } } }
///<summary> /// Create an PUT request from _input. ///</summary> ///<param name="_obj">The OgreeObject to put</param> public void CreatePutRequest(OgreeObject _obj) { SRequest request = new SRequest(); request.type = "put"; SApiObject apiObj = new SApiObject(_obj); request.path = $"/{apiObj.category}s/{apiObj.id}"; request.json = JsonConvert.SerializeObject(apiObj); requestsToSend.Enqueue(request); }
///<summary> /// Create an OgreeObject of "site" category and assign given values to it ///</summary> ///<param name="_si">The site data to apply</param> ///<param name="_parent">The parent of the created site. Leave null if _bd contains the parendId</param> ///<returns>The created Site</returns> public OgreeObject CreateSite(SApiObject _si, Transform _parent = null) { Transform tn = Utils.FindParent(_parent, _si.parentId); if (!tn || tn.GetComponent <OgreeObject>().category != "tenant") { GameManager.gm.AppendLogLine($"Parent tenant not found", true, eLogtype.error); return(null); } string hierarchyName = $"{tn.GetComponent<OgreeObject>().hierarchyName}.{_si.name}"; if (GameManager.gm.allItems.Contains(hierarchyName)) { GameManager.gm.AppendLogLine($"{hierarchyName} already exists.", true, eLogtype.warning); return(null); } GameObject newSite = new GameObject(_si.name); newSite.transform.parent = tn; OgreeObject site = newSite.AddComponent <OgreeObject>(); site.UpdateFromSApiObject(_si); switch (site.attributes["orientation"]) { case "EN": newSite.transform.localEulerAngles = new Vector3(0, 0, 0); break; case "WS": newSite.transform.localEulerAngles = new Vector3(0, 180, 0); break; case "NW": newSite.transform.localEulerAngles = new Vector3(0, -90, 0); break; case "SE": newSite.transform.localEulerAngles = new Vector3(0, 90, 0); break; } string hn = site.UpdateHierarchyName(); GameManager.gm.allItems.Add(hn, newSite); return(site); }
///<summary> /// Instantiate a buildingModel (from GameManager) and apply the given data to it. ///</summary> ///<param name="_bd">The building data to apply</param> ///<param name="_parent">The parent of the created building. Leave null if _bd contains the parendId</param> ///<returns>The created Building</returns> public Building CreateBuilding(SApiObject _bd, Transform _parent = null) { Transform si = Utils.FindParent(_parent, _bd.parentId); if (!si || si.GetComponent <OgreeObject>().category != "site") { GameManager.gm.AppendLogLine($"Parent site not found", true, eLogtype.error); return(null); } string hierarchyName = $"{si.GetComponent<OgreeObject>().hierarchyName}.{_bd.name}"; if (GameManager.gm.allItems.Contains(hierarchyName)) { GameManager.gm.AppendLogLine($"{hierarchyName} already exists.", true, eLogtype.warning); return(null); } // Position and size data from _bd.attributes Vector2 posXY = JsonUtility.FromJson <Vector2>(_bd.attributes["posXY"]); Vector2 size = JsonUtility.FromJson <Vector2>(_bd.attributes["size"]); float height = float.Parse(_bd.attributes["height"]); GameObject newBD = Instantiate(GameManager.gm.buildingModel); newBD.name = _bd.name; newBD.transform.parent = si; newBD.transform.localEulerAngles = Vector3.zero; // originalSize Vector3 originalSize = newBD.transform.GetChild(0).localScale; newBD.transform.GetChild(0).localScale = new Vector3(originalSize.x * size.x, originalSize.y, originalSize.z * size.y); Vector3 origin = newBD.transform.GetChild(0).localScale / 0.2f; newBD.transform.localPosition = new Vector3(origin.x, 0, origin.z); newBD.transform.localPosition += new Vector3(posXY.x, 0, posXY.y); Building building = newBD.GetComponent <Building>(); building.UpdateFromSApiObject(_bd); BuildWalls(building.walls, new Vector3(newBD.transform.GetChild(0).localScale.x * 10, height, newBD.transform.GetChild(0).localScale.z * 10), 0); string hn = building.UpdateHierarchyName(); GameManager.gm.allItems.Add(hn, newBD); return(building); }
///<summary> /// Move the given Transform to given position in tiles in a room. ///</summary> ///<param name="_obj">The object to move</param> ///<param name="_apiObj">The SApiObject with posXY and posU data</param> private void PlaceInRoom(Transform _obj, SApiObject _apiObj, out Vector2 _orient) { float floorUnit = GetUnitFromRoom(_obj.parent.GetComponent <Room>()); Vector2 pos = JsonUtility.FromJson <Vector2>(_apiObj.attributes["posXY"]); Vector3 origin = _obj.parent.GetChild(0).localScale / 0.2f; _obj.position = _obj.parent.GetChild(0).position; _orient = new Vector2(); if (_obj.parent.GetComponent <Room>().attributes.ContainsKey("orientation")) { if (Regex.IsMatch(_obj.parent.GetComponent <Room>().attributes["orientation"], "\\+[ENSW]{1}\\+[ENSW]{1}$")) { // Lower Left corner of the room _orient = new Vector2(1, 1); } else if (Regex.IsMatch(_obj.parent.GetComponent <Room>().attributes["orientation"], "\\-[ENSW]{1}\\+[ENSW]{1}$")) { // Lower Right corner of the room _orient = new Vector2(-1, 1); if (_apiObj.category == "rack") { _obj.localPosition -= new Vector3(_obj.GetChild(0).localScale.x, 0, 0); } } else if (Regex.IsMatch(_obj.parent.GetComponent <Room>().attributes["orientation"], "\\-[ENSW]{1}\\-[ENSW]{1}$")) { // Upper Right corner of the room _orient = new Vector2(-1, -1); if (_apiObj.category == "rack") { _obj.localPosition -= new Vector3(_obj.GetChild(0).localScale.x, 0, _obj.GetChild(0).localScale.z); } } else if (Regex.IsMatch(_obj.parent.GetComponent <Room>().attributes["orientation"], "\\+[ENSW]{1}\\-[ENSW]{1}$")) { // Upper Left corner of the room _orient = new Vector2(1, -1); if (_apiObj.category == "rack") { _obj.localPosition -= new Vector3(0, 0, _obj.GetChild(0).localScale.z); } } } // Go to the right corner of the room & apply pos _obj.localPosition += new Vector3(origin.x * -_orient.x, 0, origin.z * -_orient.y); _obj.localPosition += new Vector3(pos.x * _orient.x, 0, pos.y * _orient.y) * floorUnit; }
///<summary> /// Set temperature attribute and create/update related sensor object. ///</summary> ///<param name="_value">The temperature value</param> public async void SetTemperature(string _value) { if (category == "corridor") { if (Regex.IsMatch(_value, "^(cold|warm)$")) { attributes["temperature"] = _value; } else { GameManager.gm.AppendLogLine("Temperature must be \"cold\" or \"warm\"", true, eLogtype.warning); } } else { if (Regex.IsMatch(_value, "^[0-9.]+$")) { attributes["temperature"] = _value; GameObject sensor = GameManager.gm.FindByAbsPath($"{hierarchyName}.sensor"); if (sensor) { sensor.GetComponent <Sensor>().SetAttribute("temperature", _value); } else { SApiObject se = new SApiObject { description = new List <string>(), attributes = new Dictionary <string, string>(), name = "sensor", // ? category = "sensor", parentId = id, domain = domain }; se.attributes["formFactor"] = "ext"; se.attributes["temperature"] = _value; await OgreeGenerator.instance.CreateItemFromSApiObject(se, transform); } } else { GameManager.gm.AppendLogLine("Temperature must be a numeral value", true, eLogtype.warning); } } }
///<summary> /// Create OgreeObject of "tenant" category from given data. ///</summary> ///<param name="_tn">The tenant data to apply</param> ///<returns>The created Tenant</returns> public OgreeObject CreateTenant(SApiObject _tn) { if (GameManager.gm.allItems.Contains(_tn.name)) { GameManager.gm.AppendLogLine($"{_tn.name} already exists.", true, eLogtype.error); return(null); } GameObject newTenant = new GameObject(_tn.name); OgreeObject tenant = newTenant.AddComponent <OgreeObject>(); tenant.UpdateFromSApiObject(_tn); tenant.UpdateHierarchyName(); GameManager.gm.allItems.Add(_tn.name, newTenant); return(tenant); }
///<summary> /// Deserialize given SApiObject and call the good generator. ///</summary> ///<param name="_input">The SApiObject to deserialize</param> private async void CreateObjectFromData(string _input) { SApiObject src = JsonConvert.DeserializeObject <SApiObject>(_input); List <SApiObject> physicalObjects = new List <SApiObject>(); List <SApiObject> logicalObjects = new List <SApiObject>(); Utils.ParseNestedObjects(physicalObjects, logicalObjects, src); foreach (SApiObject obj in physicalObjects) { await OgreeGenerator.instance.CreateItemFromSApiObject(obj); } foreach (SApiObject obj in logicalObjects) { await OgreeGenerator.instance.CreateItemFromSApiObject(obj); } }
///<summary> /// Update the OObject attributes with given SApiObject. ///</summary> ///<param name="_src">The SApiObject used to update attributes</param> public override void UpdateFromSApiObject(SApiObject _src) { name = _src.name; id = _src.id; parentId = _src.parentId; category = _src.category; if (domain != _src.domain) { domain = _src.domain; UpdateColorByTenant(); } description = _src.description; if (attributes.ContainsKey("temperature") && _src.attributes.ContainsKey("temperature") && attributes["temperature"] != _src.attributes["temperature"]) { SetTemperature(_src.attributes["temperature"]); } else if (!attributes.ContainsKey("temperature") && _src.attributes.ContainsKey("temperature")) { SetTemperature(_src.attributes["temperature"]); } else if (attributes.ContainsKey("temperature") && !_src.attributes.ContainsKey("temperature")) { Destroy(transform.Find("sensor").gameObject); } attributes = _src.attributes; if (transform.parent?.GetComponent <OgreeObject>().category == "room") { referent = this; } else if (transform.parent.GetComponent <OObject>().referent != null) { referent = transform.parent.GetComponent <OObject>().referent; } else { referent = null; } }
///<summary> /// Deserialize given SApiObject and apply modification to corresponding object. ///</summary> ///<param name="_input">The SApiObject to deserialize</param> private void ModifyObject(string _input) { SApiObject newData = JsonConvert.DeserializeObject <SApiObject>(_input); OgreeObject obj = Utils.GetObjectById(newData.id).GetComponent <OgreeObject>(); // Case domain for all OgreeObjects bool tenantColorChanged = false; if (newData.category == "tenant" && obj.attributes["color"] != newData.attributes["color"]) { tenantColorChanged = true; } // Case color/temperature for racks & devices if (newData.category == "rack" || newData.category == "device") { OObject item = (OObject)obj; if (newData.attributes.ContainsKey("color")) { if ((obj.attributes.ContainsKey("color") && obj.attributes["color"] != newData.attributes["color"]) || !item.attributes.ContainsKey("color")) { item.SetColor(newData.attributes["color"]); } } if (newData.attributes.ContainsKey("temperature")) { if ((obj.attributes.ContainsKey("temperature") && obj.attributes["temperature"] != newData.attributes["temperature"]) || !item.attributes.ContainsKey("temperature")) { item.SetTemperature(newData.attributes["temperature"]); } } } // Case of a separator/areas modification in a room if (newData.category == "room") { Room room = (Room)obj; if (newData.attributes.ContainsKey("separators")) { if ((room.attributes.ContainsKey("separators") && room.attributes["separators"] != newData.attributes["separators"]) || !room.attributes.ContainsKey("separators")) { foreach (Transform wall in room.walls) { if (wall.name.Contains("separator")) { Object.Destroy(wall.gameObject); } } List <ReadFromJson.SSeparator> separators = JsonConvert.DeserializeObject <List <ReadFromJson.SSeparator> >(newData.attributes["separators"]); foreach (ReadFromJson.SSeparator sep in separators) { room.AddSeparator(sep); } } } if (newData.attributes.ContainsKey("reserved")) { if ((room.attributes.ContainsKey("reserved") && room.attributes["reserved"] != newData.attributes["reserved"]) || !room.attributes.ContainsKey("reserved")) { SMargin reserved = JsonUtility.FromJson <SMargin>(newData.attributes["reserved"]); SMargin technical = JsonUtility.FromJson <SMargin>(newData.attributes["technical"]); room.SetAreas(reserved, technical); } } } obj.UpdateFromSApiObject(newData); if (tenantColorChanged) { EventManager.Instance.Raise(new UpdateTenantEvent { name = newData.name }); } }
///<summary> /// Call the good CreateX function according to the item's category. ///</summary> ///<param name="_obj">The item to generate</param> public async Task <OgreeObject> CreateItemFromSApiObject(SApiObject _obj, Transform _parent = null) { OgreeObject newItem; // Get dependencies from API if (_obj.category != "tenant" && !string.IsNullOrEmpty(_obj.domain) && !GameManager.gm.allItems.Contains(_obj.domain)) { await ApiManager.instance.GetObject($"tenants?name={_obj.domain}", ApiManager.instance.DrawObject); } if (_obj.category == "room" && !string.IsNullOrEmpty(_obj.attributes["template"]) && !GameManager.gm.roomTemplates.ContainsKey(_obj.attributes["template"])) { Debug.Log($"Get template \"{_obj.attributes["template"]}\" from API"); await ApiManager.instance.GetObject($"room-templates/{_obj.attributes["template"]}", ApiManager.instance.DrawObject); } if ((_obj.category == "rack" || _obj.category == "device") && !string.IsNullOrEmpty(_obj.attributes["template"]) && !GameManager.gm.objectTemplates.ContainsKey(_obj.attributes["template"])) { Debug.Log($"Get template \"{_obj.attributes["template"]}\" from API"); await ApiManager.instance.GetObject($"obj-templates/{_obj.attributes["template"]}", ApiManager.instance.DrawObject); } // Call Create function switch (_obj.category) { case "tenant": newItem = customerGenerator.CreateTenant(_obj); break; case "site": newItem = customerGenerator.CreateSite(_obj, _parent); break; case "building": newItem = buildingGenerator.CreateBuilding(_obj, _parent); break; case "room": newItem = buildingGenerator.CreateRoom(_obj, _parent); break; case "rack": newItem = objectGenerator.CreateRack(_obj, _parent); break; case "device": newItem = objectGenerator.CreateDevice(_obj, _parent); break; case "corridor": newItem = objectGenerator.CreateCorridor(_obj, _parent); break; case "group": newItem = objectGenerator.CreateGroup(_obj, _parent); break; case "sensor": newItem = objectGenerator.CreateSensor(_obj, _parent); break; default: newItem = null; GameManager.gm.AppendLogLine($"Unknown object type ({_obj.category})", true, eLogtype.error); break; } ResetCoroutine(); return(newItem); }
///<summary> /// Generate a sensor (from GameManager.sensorExtModel/sensorIntModel) with defined temperature. ///</summary> ///<param name="_se">The sensor data to apply</param> ///<param name="_parent">The parent of the created sensor. Leave null if _se contains the parendId</param> ///<returns>The created sensor</returns> public Sensor CreateSensor(SApiObject _se, Transform _parent = null) { Transform parent = Utils.FindParent(_parent, _se.parentId); if (!parent) { GameManager.gm.AppendLogLine($"Parent not found", true, eLogtype.error); return(null); } string parentCategory = parent.GetComponent <OgreeObject>().category; if (_se.attributes["formFactor"] == "ext" && (parentCategory != "rack" && parentCategory != "device")) { GameManager.gm.AppendLogLine("An external sensor must be child of a rack or a device", true, eLogtype.error); return(null); } if (_se.attributes["formFactor"] == "int" && (parentCategory != "room" && parentCategory != "rack" && parentCategory != "device")) { GameManager.gm.AppendLogLine("An internal sensor must be child of a room, a rack or a device", true, eLogtype.error); return(null); } string hierarchyName = $"{parent.GetComponent<OgreeObject>().hierarchyName}.{_se.name}"; if (GameManager.gm.allItems.Contains(hierarchyName)) { GameManager.gm.AppendLogLine($"{hierarchyName} already exists.", true, eLogtype.warning); return(null); } GameObject newSensor; if (_se.attributes["formFactor"] == "ext") //Dimensions : 80 x 26 x 18 mm { newSensor = Instantiate(GameManager.gm.sensorExtModel, _parent); newSensor.name = "sensor"; Vector3 parentSize = _parent.GetChild(0).localScale; Vector3 boxSize = newSensor.transform.GetChild(0).localScale; newSensor.transform.localPosition = new Vector3(-parentSize.x, parentSize.y, parentSize.z) / 2; newSensor.transform.localPosition += new Vector3(boxSize.x, -boxSize.y, 0) / 2; } else { newSensor = Instantiate(GameManager.gm.sensorIntModel, _parent); newSensor.name = _se.name; if (parentCategory == "room") { PlaceInRoom(newSensor.transform, _se, out Vector2 orient); // Adjust position float floorUnit = GetUnitFromRoom(parent.GetComponent <Room>()); newSensor.transform.localPosition += new Vector3(floorUnit * orient.x, 0, floorUnit * orient.y) / 2; newSensor.transform.localEulerAngles = new Vector3(0, 180, 0); float posU = float.Parse(_se.attributes["posU"]); if (posU == 0) { newSensor.transform.localPosition += Vector3.up; } else { newSensor.transform.localScale = 5 * GameManager.gm.uSize * Vector3.one; newSensor.transform.localPosition += Vector3.up * (posU * GameManager.gm.uSize); } } else { newSensor.transform.localPosition = parent.GetChild(0).localScale / -2; // Assuming given pos is in mm Vector2 posXY = JsonUtility.FromJson <Vector2>(_se.attributes["posXY"]); Vector3 newPos = new Vector3(posXY.x, float.Parse(_se.attributes["posU"]), posXY.y) / 1000; newSensor.transform.localPosition += newPos; newSensor.transform.GetChild(0).localScale = Vector3.one * 0.05f; newSensor.transform.localEulerAngles = Vector3.zero; } } Sensor sensor = newSensor.GetComponent <Sensor>(); sensor.UpdateFromSApiObject(_se); sensor.UpdateSensorColor(); newSensor.GetComponent <DisplayObjectData>().PlaceTexts("front"); newSensor.GetComponent <DisplayObjectData>().SetLabel("#temperature"); string hn = sensor.UpdateHierarchyName(); GameManager.gm.allItems.Add(hn, newSensor); return(sensor); }
///<summary> /// Instantiate a deviceModel or a deviceTemplate (from GameManager) and apply given data to it. ///</summary> ///<param name="_dv">The device data to apply</param> ///<param name="_parent">The parent of the created device. Leave null if _dv contains the parendId</param> ///<returns>The created Device</returns> public OObject CreateDevice(SApiObject _dv, Transform _parent = null) { // Check parent & parent category Transform parent = Utils.FindParent(_parent, _dv.parentId); if (!parent || parent.GetComponent <OObject>() == null) { GameManager.gm.AppendLogLine($"Device must be child of a Rack or another Device", true, eLogtype.error); return(null); } // Check parent for subdevice if (parent.GetComponent <Rack>() == null && (string.IsNullOrEmpty(_dv.attributes["slot"]) || string.IsNullOrEmpty(_dv.attributes["template"]))) { GameManager.gm.AppendLogLine("A sub-device needs to be declared with a parent's slot and a template", true, eLogtype.error); return(null); } // Check if parent not hidden in a group if (parent.gameObject.activeSelf == false) { GameManager.gm.AppendLogLine("The parent object must be active (not hidden in a group)", true, eLogtype.error); return(null); } // Check if unique hierarchyName string hierarchyName = $"{parent.GetComponent<OgreeObject>().hierarchyName}.{_dv.name}"; if (GameManager.gm.allItems.Contains(hierarchyName)) { GameManager.gm.AppendLogLine($"{hierarchyName} already exists.", true, eLogtype.warning); return(null); } // Check template if (!string.IsNullOrEmpty(_dv.attributes["template"]) && !GameManager.gm.objectTemplates.ContainsKey(_dv.attributes["template"])) { GameManager.gm.AppendLogLine($"Unknown template \"{_dv.attributes["template"]}\"", true, eLogtype.error); return(null); } // Check slot Transform slot = null; if (!string.IsNullOrEmpty(_dv.attributes["slot"])) { List <Slot> takenSlots = new List <Slot>(); int i = 0; float max; if (string.IsNullOrEmpty(_dv.attributes["template"])) { max = float.Parse(_dv.attributes["sizeU"]); } else { max = float.Parse(GameManager.gm.objectTemplates[_dv.attributes["template"]].GetComponent <OgreeObject>().attributes["height"]) / 1000 / GameManager.gm.uSize; } foreach (Transform child in parent) { if ((child.name == _dv.attributes["slot"] || (i > 0 && i < max)) && child.GetComponent <Slot>()) { takenSlots.Add(child.GetComponent <Slot>()); i++; } } if (takenSlots.Count > 0) { foreach (Slot s in takenSlots) { s.SlotTaken(true); } slot = takenSlots[0].transform; } else { GameManager.gm.AppendLogLine($"Slot {_dv.attributes["slot"]} not found in {parent.name}", true, eLogtype.error); return(null); } } // Generate device GameObject newDevice; Vector2 size; float height; if (string.IsNullOrEmpty(_dv.attributes["template"])) { newDevice = GenerateBasicDevice(parent, Utils.ParseDecFrac(_dv.attributes["height"]), slot); Vector3 boxSize = newDevice.transform.GetChild(0).localScale; size = new Vector2(boxSize.x, boxSize.z); height = boxSize.y; } else { newDevice = GenerateTemplatedDevice(parent, _dv.attributes["template"]); OgreeObject tmp = newDevice.GetComponent <OgreeObject>(); size = JsonUtility.FromJson <Vector2>(tmp.attributes["size"]) / 1000; height = float.Parse(tmp.attributes["height"]) / 1000; } // Place the device if (!string.IsNullOrEmpty(_dv.attributes["slot"])) { newDevice.transform.localEulerAngles = slot.localEulerAngles; newDevice.transform.localPosition = slot.localPosition; if (height > slot.GetChild(0).localScale.y) { newDevice.transform.localPosition += new Vector3(0, height / 2 - GameManager.gm.uSize / 2, 0); } float deltaZ = slot.GetChild(0).localScale.z - size.y; switch (_dv.attributes["orientation"]) { case "front": newDevice.transform.localPosition += new Vector3(0, 0, deltaZ / 2); break; case "rear": newDevice.transform.localPosition -= new Vector3(0, 0, deltaZ / 2); newDevice.transform.localEulerAngles += new Vector3(0, 180, 0); break; case "frontflipped": newDevice.transform.localPosition += new Vector3(0, 0, deltaZ / 2); newDevice.transform.localEulerAngles += new Vector3(0, 0, 180); break; case "rearflipped": newDevice.transform.localPosition -= new Vector3(0, 0, deltaZ / 2); newDevice.transform.localEulerAngles += new Vector3(180, 0, 0); break; } // if slot, color Material mat = newDevice.transform.GetChild(0).GetComponent <Renderer>().material; Color slotColor = slot.GetChild(0).GetComponent <Renderer>().material.color; mat.color = new Color(slotColor.r, slotColor.g, slotColor.b); newDevice.GetComponent <OObject>().color = mat.color; } else { newDevice.transform.localEulerAngles = Vector3.zero; newDevice.transform.localPosition = new Vector3(0, (-parent.GetChild(0).localScale.y + height) / 2, 0); if (_dv.attributes.ContainsKey("posU")) { newDevice.transform.localPosition += new Vector3(0, (float.Parse(_dv.attributes["posU"]) - 1) * GameManager.gm.uSize, 0); } float deltaZ = parent.GetChild(0).localScale.z - size.y; newDevice.transform.localPosition += new Vector3(0, 0, deltaZ / 2); newDevice.GetComponent <OObject>().color = Color.white; } // Fill OObject class newDevice.name = _dv.name; OObject dv = newDevice.GetComponent <OObject>(); dv.UpdateFromSApiObject(_dv); // Set labels if (string.IsNullOrEmpty(dv.attributes["slot"])) { newDevice.GetComponent <DisplayObjectData>().PlaceTexts("frontrear"); } else { newDevice.GetComponent <DisplayObjectData>().PlaceTexts(slot?.GetComponent <Slot>().labelPos); } newDevice.GetComponent <DisplayObjectData>().SetLabel("#name"); string hn = dv.UpdateHierarchyName(); GameManager.gm.allItems.Add(hn, newDevice); if (!string.IsNullOrEmpty(_dv.attributes["template"])) { OObject[] components = newDevice.transform.GetComponentsInChildren <OObject>(); foreach (OObject comp in components) { if (comp.gameObject != newDevice) { comp.domain = dv.domain; string compHn = comp.UpdateHierarchyName(); GameManager.gm.allItems.Add(compHn, comp.gameObject); comp.referent = dv.referent; } } } return(dv); }
///<summary> /// Instantiate a rackModel or a rackTemplate (from GameManager) and apply the given data to it. ///</summary> ///<param name="_rk">The rack data to apply</param> ///<param name="_parent">The parent of the created rack. Leave null if _rk contains the parendId</param> ///<returns>The created Rack</returns> public Rack CreateRack(SApiObject _rk, Transform _parent = null) { Transform parent = Utils.FindParent(_parent, _rk.parentId); if (!parent || parent.GetComponent <OgreeObject>().category != "room") { GameManager.gm.AppendLogLine($"Parent room not found", true, eLogtype.error); return(null); } string hierarchyName = $"{parent.GetComponent<OgreeObject>().hierarchyName}.{_rk.name}"; if (GameManager.gm.allItems.Contains(hierarchyName)) { GameManager.gm.AppendLogLine($"{hierarchyName} already exists.", true, eLogtype.warning); return(null); } GameObject newRack; if (string.IsNullOrEmpty(_rk.attributes["template"])) { newRack = Instantiate(GameManager.gm.rackModel); } else { if (GameManager.gm.objectTemplates.ContainsKey(_rk.attributes["template"])) { newRack = Instantiate(GameManager.gm.objectTemplates[_rk.attributes["template"]]); } else { GameManager.gm.AppendLogLine($"Unknown template \"{_rk.attributes["template"]}\"", true, eLogtype.error); return(null); } Renderer[] renderers = newRack.GetComponentsInChildren <Renderer>(); foreach (Renderer r in renderers) { r.enabled = true; } newRack.transform.GetChild(0).GetComponent <Collider>().enabled = true; } newRack.name = _rk.name; newRack.transform.parent = parent; if (string.IsNullOrEmpty(_rk.attributes["template"])) { Vector2 size = JsonUtility.FromJson <Vector2>(_rk.attributes["size"]); float height = float.Parse(_rk.attributes["height"]); if (_rk.attributes["heightUnit"] == "U") { height *= GameManager.gm.uSize; } else if (_rk.attributes["heightUnit"] == "cm") { height /= 100; } newRack.transform.GetChild(0).localScale = new Vector3(size.x / 100, height, size.y / 100); } PlaceInRoom(newRack.transform, _rk, out Vector2 orient); Rack rack = newRack.GetComponent <Rack>(); rack.UpdateFromSApiObject(_rk); // Correct position according to rack size & rack orientation Vector3 boxOrigin; Transform box = newRack.transform.GetChild(0); if (box.childCount == 0) { boxOrigin = box.localScale / 2; } else { boxOrigin = box.GetComponent <BoxCollider>().size / 2; } float floorUnit = GetUnitFromRoom(parent.GetComponent <Room>()); Vector3 fixPos = Vector3.zero; switch (rack.attributes["orientation"]) { case "front": newRack.transform.localEulerAngles = new Vector3(0, 180, 0); if (orient.y == 1) { fixPos = new Vector3(boxOrigin.x, boxOrigin.y, boxOrigin.z); } else { fixPos = new Vector3(boxOrigin.x, boxOrigin.y, boxOrigin.z + floorUnit); } break; case "rear": newRack.transform.localEulerAngles = new Vector3(0, 0, 0); if (orient.y == 1) { fixPos = new Vector3(boxOrigin.x, boxOrigin.y, -boxOrigin.z + floorUnit); } else { fixPos = new Vector3(boxOrigin.x, boxOrigin.y, boxOrigin.z); } break; case "left": newRack.transform.localEulerAngles = new Vector3(0, 90, 0); if (orient.x == 1) { fixPos = new Vector3(-boxOrigin.z + floorUnit, boxOrigin.y, boxOrigin.x); } else { fixPos = new Vector3(boxOrigin.z, boxOrigin.y, boxOrigin.x); } break; case "right": newRack.transform.localEulerAngles = new Vector3(0, -90, 0); if (orient.x == 1) { fixPos = new Vector3(boxOrigin.z, boxOrigin.y, -boxOrigin.x + floorUnit); } else { fixPos = new Vector3(-boxOrigin.z + floorUnit, boxOrigin.y, -boxOrigin.x + floorUnit); } break; } newRack.transform.localPosition += fixPos; newRack.GetComponent <DisplayObjectData>().PlaceTexts("frontrear"); newRack.GetComponent <DisplayObjectData>().SetLabel("#name"); rack.UpdateColorByTenant(); string hn = rack.UpdateHierarchyName(); GameManager.gm.allItems.Add(hn, newRack); if (!string.IsNullOrEmpty(rack.attributes["template"])) { OObject[] components = rack.transform.GetComponentsInChildren <OObject>(); foreach (OObject comp in components) { if (comp.gameObject != rack.gameObject) { comp.domain = rack.domain; string compHn = comp.UpdateHierarchyName(); GameManager.gm.allItems.Add(compHn, comp.gameObject); comp.referent = rack; } } } return(rack); }
///<summary> /// Instantiate a roomModel (from GameManager) and apply given data to it. ///</summary> ///<param name="_ro">The room data to apply</param> ///<param name="_parent">The parent of the created room. Leave null if _bd contains the parendId</param> ///<returns>The created Room</returns> public Room CreateRoom(SApiObject _ro, Transform _parent = null) { Transform bd = Utils.FindParent(_parent, _ro.parentId); if (!bd || bd.GetComponent <OgreeObject>().category != "building") { GameManager.gm.AppendLogLine($"Parent building not found", true, eLogtype.error); return(null); } string hierarchyName = $"{bd.GetComponent<OgreeObject>().hierarchyName}.{_ro.name}"; if (GameManager.gm.allItems.Contains(hierarchyName)) { GameManager.gm.AppendLogLine($"{hierarchyName} already exists.", true, eLogtype.warning); return(null); } // Position and size data from _ro.attributes Vector2 posXY = JsonUtility.FromJson <Vector2>(_ro.attributes["posXY"]); Vector2 size = JsonUtility.FromJson <Vector2>(_ro.attributes["size"]); float height = float.Parse(_ro.attributes["height"]); GameObject newRoom = Instantiate(GameManager.gm.roomModel); newRoom.name = _ro.name; newRoom.transform.parent = bd; Room room = newRoom.GetComponent <Room>(); room.UpdateFromSApiObject(_ro); Vector3 originalSize = room.usableZone.localScale; room.usableZone.localScale = new Vector3(originalSize.x * size.x, originalSize.y, originalSize.z * size.y); room.reservedZone.localScale = room.usableZone.localScale; room.technicalZone.localScale = room.usableZone.localScale; room.tilesEdges.localScale = room.usableZone.localScale; room.tilesEdges.GetComponent <Renderer>().material.mainTextureScale = size / 0.6f; room.tilesEdges.GetComponent <Renderer>().material.mainTextureOffset = new Vector2(size.x / 0.6f % 1, size.y / 0.6f % 1); BuildWalls(room.walls, new Vector3(room.usableZone.localScale.x * 10, height, room.usableZone.localScale.z * 10), -0.001f); Vector3 bdOrigin = bd.GetChild(0).localScale / -0.2f; Vector3 roOrigin = room.usableZone.localScale / 0.2f; newRoom.transform.position = bd.position; newRoom.transform.localPosition += new Vector3(bdOrigin.x, 0, bdOrigin.z); newRoom.transform.localPosition += new Vector3(posXY.x, 0, posXY.y); if (Regex.IsMatch(room.attributes["orientation"], "(\\+|\\-)E(\\+|\\-)N")) { newRoom.transform.eulerAngles = new Vector3(0, 0, 0); newRoom.transform.position += new Vector3(roOrigin.x, 0, roOrigin.z); } else if (Regex.IsMatch(room.attributes["orientation"], "(\\+|\\-)W(\\+|\\-)S")) { newRoom.transform.eulerAngles = new Vector3(0, 180, 0); newRoom.transform.position += new Vector3(-roOrigin.x, 0, -roOrigin.z); } else if (Regex.IsMatch(room.attributes["orientation"], "(\\+|\\-)N(\\+|\\-)W")) { newRoom.transform.eulerAngles = new Vector3(0, -90, 0); newRoom.transform.position += new Vector3(-roOrigin.z, 0, roOrigin.x); } else if (Regex.IsMatch(room.attributes["orientation"], "(\\+|\\-)S(\\+|\\-)E")) { newRoom.transform.eulerAngles = new Vector3(0, 90, 0); newRoom.transform.position += new Vector3(roOrigin.z, 0, -roOrigin.x); } // Set UI room's name room.nameText.text = newRoom.name; room.nameText.rectTransform.sizeDelta = size; room.UpdateZonesColor(); string hn = room.UpdateHierarchyName(); GameManager.gm.allItems.Add(hn, newRoom); if (_ro.attributes.ContainsKey("reserved") && _ro.attributes.ContainsKey("technical") && !string.IsNullOrEmpty(_ro.attributes["reserved"]) && !string.IsNullOrEmpty(_ro.attributes["technical"])) { SMargin reserved = JsonUtility.FromJson <SMargin>(_ro.attributes["reserved"]); SMargin technical = JsonUtility.FromJson <SMargin>(_ro.attributes["technical"]); room.SetAreas(reserved, technical); } if (!string.IsNullOrEmpty(_ro.attributes["template"]) && GameManager.gm.roomTemplates.ContainsKey(_ro.attributes["template"])) { ReadFromJson.SRoomFromJson template = GameManager.gm.roomTemplates[_ro.attributes["template"]]; room.SetAreas(new SMargin(template.reservedArea), new SMargin(template.technicalArea)); if (template.separators != null) { foreach (ReadFromJson.SSeparator sep in template.separators) { room.AddSeparator(sep); } } if (template.tiles != null) { List <ReadFromJson.STile> tiles = new List <ReadFromJson.STile>(); foreach (ReadFromJson.STile t in template.tiles) { tiles.Add(t); } room.attributes["tiles"] = JsonConvert.SerializeObject(tiles); } if (template.rows != null) { List <ReadFromJson.SRow> rows = new List <ReadFromJson.SRow>(); foreach (ReadFromJson.SRow r in template.rows) { rows.Add(r); } room.attributes["rows"] = JsonConvert.SerializeObject(rows); } if (template.colors != null) { List <ReadFromJson.SColor> colors = new List <ReadFromJson.SColor>(); foreach (ReadFromJson.SColor c in template.colors) { colors.Add(c); } room.attributes["customColors"] = JsonConvert.SerializeObject(colors); } } return(room); }
///<summary> /// Parse a nested SApiObject and add each item to a given list. ///</summary> ///<param name="_physicalList">The list of physical objects to complete</param> ///<param name="_logicalList">The list of logical objects to complete</param> ///<param name="_src">The head of nested SApiObjects</param> public static void ParseNestedObjects(List <SApiObject> _physicalList, List <SApiObject> _logicalList, SApiObject _src) { if (_src.category == "group") { _logicalList.Add(_src); } else { _physicalList.Add(_src); } if (_src.children != null) { foreach (SApiObject obj in _src.children) { ParseNestedObjects(_physicalList, _logicalList, obj); } } }
///<summary> /// Generate a corridor (from GameManager.labeledBoxModel) with defined corners and color. ///</summary> ///<param name="_co">The corridor data to apply</param> ///<param name="_parent">The parent of the created corridor. Leave null if _co contains the parendId</param> ///<returns>The created corridor</returns> public OObject CreateCorridor(SApiObject _co, Transform _parent = null) { Transform parent = Utils.FindParent(_parent, _co.parentId); if (!parent || parent.GetComponent <OgreeObject>().category != "room") { GameManager.gm.AppendLogLine($"Parent room not found", true, eLogtype.error); return(null); } string hierarchyName = $"{parent.GetComponent<OgreeObject>().hierarchyName}.{_co.name}"; if (GameManager.gm.allItems.Contains(hierarchyName)) { GameManager.gm.AppendLogLine($"{hierarchyName} already exists.", true, eLogtype.warning); return(null); } string roomHierarchyName = parent.GetComponent <OgreeObject>().hierarchyName; string[] rackNames = _co.attributes["content"].Split(','); Transform lowerLeft = GameManager.gm.FindByAbsPath($"{roomHierarchyName}.{rackNames[0]}")?.transform; Transform upperRight = GameManager.gm.FindByAbsPath($"{roomHierarchyName}.{rackNames[1]}")?.transform; if (lowerLeft == null || upperRight == null) { GameManager.gm.AppendLogLine($"{rackNames[0]} or {rackNames[1]} doesn't exist", true, eLogtype.error); return(null); } float maxHeight = lowerLeft.GetChild(0).localScale.y; if (upperRight.GetChild(0).localScale.y > maxHeight) { maxHeight = upperRight.GetChild(0).localScale.y; } GameObject newCo = Instantiate(GameManager.gm.labeledBoxModel); newCo.name = _co.name; newCo.transform.parent = parent; float x = upperRight.localPosition.x - lowerLeft.localPosition.x; float z = upperRight.localPosition.z - lowerLeft.localPosition.z; if (lowerLeft.GetComponent <Rack>().attributes["orientation"] == "front" || lowerLeft.GetComponent <Rack>().attributes["orientation"] == "rear") { x += (upperRight.GetChild(0).localScale.x + lowerLeft.GetChild(0).localScale.x) / 2; z -= (upperRight.GetChild(0).localScale.z + lowerLeft.GetChild(0).localScale.z) / 2; } else { x += (upperRight.GetChild(0).localScale.z + lowerLeft.GetChild(0).localScale.z) / 2; z -= (upperRight.GetChild(0).localScale.x + lowerLeft.GetChild(0).localScale.x) / 2; } newCo.transform.GetChild(0).localScale = new Vector3(x, maxHeight, z); newCo.transform.localEulerAngles = new Vector3(0, 180, 0); newCo.transform.localPosition = new Vector3(lowerLeft.localPosition.x, maxHeight / 2, lowerLeft.localPosition.z); float xOffset = (newCo.transform.GetChild(0).localScale.x - lowerLeft.GetChild(0).localScale.x) / 2; float zOffset = (newCo.transform.GetChild(0).localScale.z + lowerLeft.GetChild(0).localScale.z) / 2; newCo.transform.localPosition += new Vector3(xOffset, 0, zOffset); OObject co = newCo.AddComponent <OObject>(); co.UpdateFromSApiObject(_co); newCo.transform.GetChild(0).GetComponent <Renderer>().material = GameManager.gm.alphaMat; Material mat = newCo.transform.GetChild(0).GetComponent <Renderer>().material; mat.color = new Color(mat.color.r, mat.color.g, mat.color.b, 0.5f); if (_co.attributes["temperature"] == "cold") { co.SetAttribute("color", "000099"); } else { co.SetAttribute("color", "990000"); } newCo.GetComponent <DisplayObjectData>().PlaceTexts("top"); newCo.GetComponent <DisplayObjectData>().SetLabel("#name"); string hn = co.UpdateHierarchyName(); GameManager.gm.allItems.Add(hn, newCo); return(co); }
///<summary> /// Generate a group (from GameManager.labeledBoxModel) which contains all the given objects. ///</summary> ///<param name="_gr">The group data to apply</param> ///<param name="_parent">The parent of the created group. Leave null if _gr contains the parendId</param> ///<returns>The created rackGroup</returns> public Group CreateGroup(SApiObject _gr, Transform _parent = null) { Transform parent = Utils.FindParent(_parent, _gr.parentId); if (!parent) { GameManager.gm.AppendLogLine("Parent not found", true, eLogtype.error); return(null); } string parentCategory = parent.GetComponent <OgreeObject>().category; if (parentCategory != "room" && parentCategory != "rack") { GameManager.gm.AppendLogLine("A group must be a child of a room or a rack", true, eLogtype.error); return(null); } string hierarchyName = $"{parent.GetComponent<OgreeObject>().hierarchyName}.{_gr.name}"; if (GameManager.gm.allItems.Contains(hierarchyName)) { GameManager.gm.AppendLogLine($"{hierarchyName} already exists.", true, eLogtype.warning); return(null); } List <Transform> content = new List <Transform>(); string[] contentNames = _gr.attributes["content"].Split(','); foreach (string cn in contentNames) { GameObject go = GameManager.gm.FindByAbsPath($"{parent.GetComponent<OgreeObject>().hierarchyName}.{cn}"); if (go && go.GetComponent <OgreeObject>()) { if ((parentCategory == "room" && (go.GetComponent <OgreeObject>().category == "rack" || go.GetComponent <OgreeObject>().category == "corridor")) || parentCategory == "rack" && go.GetComponent <OgreeObject>().category == "device") { content.Add(go.transform); } } else { GameManager.gm.AppendLogLine($"{parent.GetComponent<OgreeObject>().hierarchyName}.{cn} doesn't exists.", true, eLogtype.warning); } } if (content.Count == 0) { return(null); } GameObject newGr = Instantiate(GameManager.gm.labeledBoxModel); newGr.name = _gr.name; newGr.transform.parent = parent; // According to group type, set pos, rot & scale Vector3 pos = Vector3.zero; Vector3 scale = Vector3.zero; if (parentCategory == "room") { RackGroupPosScale(content, out pos, out scale); newGr.transform.localEulerAngles = new Vector3(0, 180, 0); } else if (parentCategory == "rack") { DeviceGroupPosScale(content, out pos, out scale); newGr.transform.localEulerAngles = Vector3.zero; } newGr.transform.localPosition = pos; newGr.transform.GetChild(0).localScale = scale; // Set Group component Group gr = newGr.AddComponent <Group>(); gr.UpdateFromSApiObject(_gr); gr.UpdateColorByTenant(); gr.DisplayContent(false); if (parentCategory == "room") { newGr.GetComponent <DisplayObjectData>().PlaceTexts("top"); } else if (parentCategory == "rack") { newGr.GetComponent <DisplayObjectData>().PlaceTexts("frontrear"); } newGr.GetComponent <DisplayObjectData>().SetLabel("#name"); string hn = gr.UpdateHierarchyName(); GameManager.gm.allItems.Add(hn, newGr); return(gr); }
///<summary> /// Create a rack or a device from received data and add it to correct GameManager list ///</summary> ///<param name="_data">The data template</param> public async Task CreateObjectTemplate(STemplate _data) { if (_data.category != "rack" && _data.category != "device") { GameManager.gm.AppendLogLine($"Unknown category for {_data.slug} template.", true, eLogtype.error); return; } if (GameManager.gm.objectTemplates.ContainsKey(_data.slug)) { GameManager.gm.AppendLogLine($"{_data.slug} already exists.", false, eLogtype.warning); return; } // Build SApiObject SApiObject obj = new SApiObject { description = new List <string>(), attributes = new Dictionary <string, string>(), name = _data.slug, category = _data.category }; obj.description.Add(_data.description); if (obj.category == "rack") { Vector3 tmp = new Vector3(_data.sizeWDHmm[0], _data.sizeWDHmm[1], _data.sizeWDHmm[2]) / 10; obj.attributes["posXY"] = JsonUtility.ToJson(Vector2.zero); obj.attributes["posXYUnit"] = "tile"; obj.attributes["size"] = JsonUtility.ToJson(new Vector2(tmp.x, tmp.y)); obj.attributes["sizeUnit"] = "cm"; obj.attributes["height"] = ((int)tmp.z).ToString(); obj.attributes["heightUnit"] = "cm"; obj.attributes["orientation"] = "front"; } else if (obj.category == "device") { if (_data.attributes.ContainsKey("type") && (_data.attributes["type"] == "chassis" || _data.attributes["type"] == "server")) { int sizeU = Mathf.CeilToInt((_data.sizeWDHmm[2] / 1000) / GameManager.gm.uSize); obj.attributes["sizeU"] = sizeU.ToString(); } obj.attributes["size"] = JsonUtility.ToJson(new Vector2(_data.sizeWDHmm[0], _data.sizeWDHmm[1])); obj.attributes["sizeUnit"] = "mm"; obj.attributes["height"] = _data.sizeWDHmm[2].ToString(); obj.attributes["heightUnit"] = "mm"; obj.attributes["slot"] = ""; } obj.attributes["template"] = ""; obj.attributes["fbxModel"] = (!string.IsNullOrEmpty(_data.fbxModel)).ToString(); if (_data.attributes != null) { foreach (KeyValuePair <string, string> kvp in _data.attributes) { obj.attributes[kvp.Key] = kvp.Value; } } // Generate the 3D object OgreeObject newObject; if (obj.category == "rack") { newObject = OgreeGenerator.instance.CreateItemFromSApiObject(obj, GameManager.gm.templatePlaceholder).Result; if (!string.IsNullOrEmpty(_data.fbxModel)) { await ModelLoader.instance.ReplaceBox(newObject.gameObject, _data.fbxModel); } } else// if (obj.category == "device") { newObject = OgreeGenerator.instance.CreateItemFromSApiObject(obj, GameManager.gm.templatePlaceholder.GetChild(0)).Result; if (string.IsNullOrEmpty(_data.fbxModel)) { newObject.transform.GetChild(0).localScale = new Vector3(_data.sizeWDHmm[0], _data.sizeWDHmm[2], _data.sizeWDHmm[1]) / 1000; } else { await ModelLoader.instance.ReplaceBox(newObject.gameObject, _data.fbxModel); } } newObject.transform.localPosition = Vector3.zero; newObject.GetComponent <OObject>().color = newObject.transform.GetChild(0).GetComponent <Renderer>().material.color; // Retrieve custom colors Dictionary <string, string> customColors = new Dictionary <string, string>(); if (_data.colors != null) { foreach (SColor color in _data.colors) { customColors.Add(color.name, color.value); } } // Generate components & slots if (_data.components != null) { foreach (STemplateChild compData in _data.components) { PopulateSlot(false, compData, newObject, customColors); } } if (_data.slots != null) { foreach (STemplateChild slotData in _data.slots) { PopulateSlot(true, slotData, newObject, customColors); } } // For rack, update height counting if (newObject.category == "rack") { Slot[] slots = newObject.GetComponentsInChildren <Slot>(); if (slots.Length > 0) { int height = 0; foreach (Slot s in slots) { if (s.orient == "horizontal") { height++; } } newObject.attributes["height"] = height.ToString(); newObject.attributes["heightUnit"] = "U"; } } // Toggle renderers & put newObj in GameManager.objectTemplates #if PROD Renderer[] renderers = newObject.transform.GetComponentsInChildren <Renderer>(); foreach (Renderer r in renderers) { r.enabled = false; } newObject.transform.GetChild(0).GetComponent <Collider>().enabled = false; #endif GameManager.gm.allItems.Remove(newObject.hierarchyName); GameManager.gm.objectTemplates.Add(newObject.name, newObject.gameObject); }