diff --git a/.gitignore b/.gitignore index c211a83a6b8f994e5bbcbc32c432e61ebe8b327e..90758be5d4b8a2fdad01978ad735ba6b45bbc594 100644 --- a/.gitignore +++ b/.gitignore @@ -1,32 +1,17 @@ -# This .gitignore file should be placed at the root of your Unity project directory -# -# Get latest from https://github.com/github/gitignore/blob/master/Unity.gitignore -# +# Modified from: +# https://github.com/github/gitignore/blob/master/Unity.gitignore + /[Ll]ibrary/ -/[Tt]emp/ -/[Oo]bj/ +/[Uu]serSettings/ +[Tt]emp/ +[Oo]bj/ /[Bb]uild/ /[Bb]uilds/ /[Ll]ogs/ /[Mm]emoryCaptures/ -# Fraunhofer HHI / IMC / Unity settings -#/[Aa]ssets/Fraunhofer -/[Aa]pp -/[Bb]in -/[Ee]xe - -# Never ignore Asset meta data -!/[Aa]ssets/**/*.meta - # Uncomment this line if you wish to ignore the asset store tools plugin -# /[Aa]ssets/AssetStoreTools* - -# TextMesh Pro files -#[Aa]ssets/TextMesh*Pro/ - -# Autogenerated Jetbrains Rider plugin -[Aa]ssets/Plugins/Editor/JetBrains* +# [Aa]ssets/AssetStoreTools* # Visual Studio cache directory .vs/ @@ -65,4 +50,14 @@ sysinfo.txt *.unitypackage # Crashlytics generated file -crashlytics-build.properties \ No newline at end of file +crashlytics-build.properties + +# Windows +Thumbs.db +Thumbs.db.meta + +# MacOS +*.DS_Store + +# VS Code +*.vscode \ No newline at end of file diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFEdgeLink.cs b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFEdgeLink.cs new file mode 100644 index 0000000000000000000000000000000000000000..d579d6435e7f3538996e42e06b4c1717d7ba2fe0 --- /dev/null +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFEdgeLink.cs @@ -0,0 +1,83 @@ +// +// ARF - Augmented Reality Framework (ETSI ISG ARF) +// +// Copyright 2022 ETSI +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Last change: July 2022 +// + +using Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Windows; +using Org.OpenAPITools.Model; +using UnityEditor; +using UnityEditor.Experimental.GraphView; +using UnityEngine; +using UnityEngine.UIElements; + +namespace Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Graph +{ + public class ARFEdgeLink : Edge + { + public WorldLink worldLink; + public string GUID; + + public Image savedIcon; + + public ARFEdgeLink() + { + var doubleClickManipulator = new Clickable(Clicked); + doubleClickManipulator.activators.Clear(); + doubleClickManipulator.activators.Add(new ManipulatorActivationFilter { button = MouseButton.LeftMouse, clickCount = 2 }); + this.AddManipulator(doubleClickManipulator); + } + public void Clicked() + { + Debug.Log(worldLink.ToJson()); + GraphEditorWindow.ShowWindow(this); + } + public void MarkUnsaved() + { + if (savedIcon == null) + { + //the icon to add if the node does not correspond to an element in the server + Texture2D warningImage = (Texture2D)AssetDatabase.LoadAssetAtPath("Assets/ETSI.ARF/ARF World Storage API/Images/cloud.png", typeof(Texture2D)); + savedIcon = new Image + { + image = warningImage + }; + savedIcon.style.width = 18; + savedIcon.style.height = 18; + savedIcon.style.minWidth = 18; + savedIcon.style.minHeight = 18; + savedIcon.style.flexGrow = 1; + savedIcon.style.alignSelf = Align.Center; + + } + if (!edgeControl.Contains(savedIcon)) + { + edgeControl.Add(savedIcon); + } + tooltip = "This element is not synchronized with the World Storage"; + } + + public void MarkSaved() + { + if (edgeControl.Contains(savedIcon)) + { + edgeControl.Remove(savedIcon); + tooltip = ""; + } + } + } +} \ No newline at end of file diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/GraphWindow.cs.meta b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFEdgeLink.cs.meta similarity index 83% rename from Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/GraphWindow.cs.meta rename to Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFEdgeLink.cs.meta index dd5ac4d1813dc90ae515e789f26876dbdd5b8c86..723d9ee5a57433d64e93157394dddc87a891f90e 100644 --- a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/GraphWindow.cs.meta +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFEdgeLink.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 8dd64e8d8a545ab45b424402550b55a6 +guid: 81a94cf483be20040aa4fe8d9f93d5c5 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFGraphView.cs b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFGraphView.cs index 299379076fe047f641b17c045c9ee553bf885e69..f1038c2c65353d9b4df4cf1b04c743f1d4ccb6f6 100644 --- a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFGraphView.cs +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFGraphView.cs @@ -1,109 +1,651 @@ -// -// ARF - Augmented Reality Framework (ETSI ISG ARF) -// -// Copyright 2022 ETSI -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Last change: June 2022 -// - -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UIElements; -using UnityEditor.Experimental.GraphView; -using System; - -namespace ETSI.ARF.WorldStorage.UI -{ - public class ARFGraphView : GraphView - { - public ARFGraphView() - { - //GridBackground back = new GridBackground(); - //back.StretchToParentSize(); - //Insert(0, back); - - this.AddManipulator(new ContentDragger()); - this.AddManipulator(new SelectionDragger()); - this.AddManipulator(new RectangleSelector()); - - AddElement(GenerateEntryPointNode()); - } - - public override List GetCompatiblePorts(Port startPort, NodeAdapter nodeAdapter) - { - var cPorts = new List(); - ports.ForEach (funcCall: port => - { - if (startPort != port && startPort.node != port.node) cPorts.Add(port); - }); - return cPorts; - } - - private Port GeneratePort (ARFNode node, Direction portDirection, Port.Capacity capacity = Port.Capacity.Multi) - { - return node.InstantiatePort(Orientation.Horizontal, portDirection, capacity, typeof(int)); // dummy - } - - private ARFNode GenerateEntryPointNode() - { - var node = new ARFNode - { - title = "World Storage", - text = "EntryPoint", - GUID = Guid.NewGuid().ToString(), - entryPoint = true - }; - - var portOut = GeneratePort(node, Direction.Output); - portOut.portName = "Link"; - node.outputContainer.Add(portOut); - - node.RefreshExpandedState(); - node.RefreshPorts(); - node.SetPosition(new Rect(50, 100, 200, 150)); - return node; - } - - public void CreateNode(string name) - { - AddElement(CreateARFNode(name)); - } - - public ARFNode CreateARFNode(string name) - { - var node = new ARFNode - { - title = name, - text = name, - GUID = Guid.NewGuid().ToString() - }; - - var portIn = GeneratePort(node, Direction.Input, Port.Capacity.Multi); - portIn.portName = "Link"; // "Input"; - node.inputContainer.Add(portIn); - - var portOut = GeneratePort(node, Direction.Output, Port.Capacity.Multi); - portOut.portName = "Link"; // "Output"; - node.outputContainer.Add(portOut); - - node.RefreshExpandedState(); - node.RefreshPorts(); - node.SetPosition(new Rect(200, 100, 200, 150)); - - return node; - } - } +// +// ARF - Augmented Reality Framework (ETSI ISG ARF) +// +// Copyright 2022 ETSI +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Last change: July 2022 +// + +#define USING_OPENAPI_GENERATOR + +using System.Collections.Generic; +#if USING_OPENAPI_GENERATOR +using Org.OpenAPITools.Model; +#else +using IO.Swagger.Api; +using IO.Swagger.Model; +#endif +using UnityEngine; +using UnityEngine.UIElements; +using UnityEditor.Experimental.GraphView; +using System; +using Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Graph; +using ETSI.ARF.WorldStorage.REST; +using UnityEditor; +using Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Windows; +using System.Linq; + +namespace ETSI.ARF.WorldStorage.UI +{ + public class ARFGraphView : GraphView + { + public WorldStorageServer worldStorageServer; + public WorldStorageUser worldStorageUser; + + public ARFGraphView() + { + SetupZoom(ContentZoomer.DefaultMinScale, ContentZoomer.DefaultMaxScale); + + //deleSection + deleteSelection += DeleteFunc; + + + this.AddManipulator(new ContentDragger()); + this.AddManipulator(new SelectionDragger()); + this.AddManipulator(new RectangleSelector()); + + } + + //method called when an element is deleted from the graphview + public void DeleteFunc(string operationName, AskUser askUser) + { + //build the message to list all the deleted elements + String message = "Are you sure you want to delete "; + if (selection.Count > 1) + { + message += selection.Count + " elements ?"; + } + else + { + message += "this element ?"; + } + + //remove from the graph all the deleted elements + if (EditorUtility.DisplayDialog("Deleting elements", message, "Yes", "No")) + { + if (SaveInfo.instance.elemsToRemove == null) + { + SaveInfo.instance.elemsToRemove = new Dictionary(); + } + foreach (GraphElement elt in selection.ToArray()) + { + ARFNodeWorldAnchor nodeAnchor = elt as ARFNodeWorldAnchor; + if (nodeAnchor != null) + { + nodeAnchor.DisconnectAllPorts(this); + if (SaveInfo.instance.nodePositions.ContainsKey(nodeAnchor.GUID)) + { + SaveInfo.instance.elemsToRemove.Add(nodeAnchor.GUID, typeof(WorldAnchor)); + } + RemoveElement(elt); + continue; + } + ARFNodeTrackable nodeTrackable = elt as ARFNodeTrackable; + if (nodeTrackable != null) + { + nodeTrackable.DisconnectAllPorts(this); + if (SaveInfo.instance.nodePositions.ContainsKey(nodeTrackable.GUID)) + { + SaveInfo.instance.elemsToRemove.Add(nodeTrackable.GUID, typeof(Trackable)); + } + RemoveElement(elt); + continue; + } + ARFEdgeLink edgeLink = elt as ARFEdgeLink; + if (edgeLink != null) + { + edgeLink.input.Disconnect(edgeLink); + edgeLink.output.Disconnect(edgeLink); + if (SaveInfo.instance.linkIds.Contains(edgeLink.GUID)) + { + SaveInfo.instance.elemsToRemove.Add(edgeLink.GUID, typeof(WorldLink)); + } + RemoveElement(elt); + continue; + } + } + } + + GraphEditorWindow.ResetWindow(); + } + + public override void BuildContextualMenu(UnityEngine.UIElements.ContextualMenuPopulateEvent evt) + { + Vector2 localMousePos = evt.localMousePosition; + Vector2 actualGraphPosition = viewTransform.matrix.inverse.MultiplyPoint(localMousePos); + + if (!(evt.target is ARFNode || evt.target is Group || evt.target is ARFEdgeLink)) + { + evt.menu.AppendSeparator(); + evt.menu.AppendAction("Save graph", delegate + { + if (ServerAndLocalDifferent()) + { + SaveInServer(); + } + }, (DropdownMenuAction a) => DropdownMenuAction.Status.Normal); + evt.menu.AppendAction("Reload graph", delegate + { + if (ServerAndLocalDifferent() && EditorUtility.DisplayDialog("Saving node positions", "The World Graph has been modified. \nWould you like to push the modifications to the server ?", "Yes", "No")) + { + SaveInServer(); + } + Reload(); + SaveInfo.instance.toReFrame = true; + }, (DropdownMenuAction a) => DropdownMenuAction.Status.Normal); + evt.menu.AppendAction("Create Trackable", delegate + { + //generate the Trackables's attributes + EncodingInformationStructure trackableEncodingInformation = new EncodingInformationStructure(EncodingInformationStructure.DataFormatEnum.OTHER, "0"); + + List localCRS = new(); + for (int i = 0; i < 15; i++) + { + localCRS.Add(0); + } + localCRS.Add(1); + + List trackableSize = new(); + for (int i = 0; i < 3; i++) + { + trackableSize.Add(0); + } + + string name = "DefaultTrackable"; + + //trying to add number after default name + var defaultNodes = nodes.ToList().Where(node => node.title.StartsWith("DefaultTrackable")); + if (defaultNodes.Any()) + { + for (int i = 0; i < defaultNodes.Count(); i++) + { + Debug.Log($"{i} : " + defaultNodes.ElementAt(i).title); + if (!(defaultNodes.Where(node => node.title.EndsWith((i + 1).ToString() + ")")).Any())) + { + name = name + " (" + (i + 1).ToString() + ")"; + break; + } + } + } + + Trackable trackable = new Trackable(Guid.NewGuid(), name, Guid.Parse(worldStorageUser.UUID), Trackable.TrackableTypeEnum.OTHER, trackableEncodingInformation, new byte[64], localCRS, UnitSystem.CM, trackableSize, new Dictionary>()); + + selection.Clear(); + var node = CreateTrackableNode(trackable, actualGraphPosition.x, actualGraphPosition.y); + node.MarkUnsaved(); + GraphEditorWindow.ShowWindow((ARFNodeTrackable)node); + + }, (DropdownMenuAction a) => DropdownMenuAction.Status.Normal); + evt.menu.AppendAction("Create World Anchor", delegate + { + //generate the worldAnchor attributes + List localCRS = new List(); + for (int i = 0; i < 15; i++) + { + localCRS.Add(0); + } + localCRS.Add(1); + + List worldAnchorSize = new List(); + for (int i = 0; i < 3; i++) + { + worldAnchorSize.Add(0); + } + + string name = "DefaultWorldAnchor"; + + //trying to add number after default name + var defaultNodes = nodes.ToList().Where(node => node.title.StartsWith("DefaultWorldAnchor")); + if (defaultNodes.Any()) + { + for (int i = 0; i < defaultNodes.Count(); i++) + { + if (!(defaultNodes.Where(node => node.title.EndsWith((i + 1).ToString() + ")")).Any())) + { + name = name + " (" + (i + 1).ToString() + ")"; + break; + } + } + } + + WorldAnchor anchor = new WorldAnchor(Guid.NewGuid(), name, Guid.Parse(worldStorageUser.UUID), localCRS, UnitSystem.CM, worldAnchorSize, new Dictionary>()); + + selection.Clear(); + var node = CreateAnchorNode(anchor, actualGraphPosition.x, actualGraphPosition.y); + node.MarkUnsaved(); + GraphEditorWindow.ShowWindow((ARFNodeWorldAnchor)node); + + }, (DropdownMenuAction a) => DropdownMenuAction.Status.Normal); + } + evt.menu.AppendSeparator(); + if (evt.target is ARFNode || evt.target is Group || evt.target is ARFEdgeLink) + { + evt.menu.AppendSeparator(); + evt.menu.AppendAction("Delete", delegate + { + DeleteSelectionCallback(AskUser.AskUser); + }, (DropdownMenuAction a) => canDeleteSelection ? DropdownMenuAction.Status.Normal : DropdownMenuAction.Status.Disabled); + evt.menu.AppendSeparator(); + } + } + + public bool ServerAndLocalDifferent() + { + if ((SaveInfo.instance.elemsToRemove.Count != 0) || (SaveInfo.instance.elemsToUpdate.Count != 0)) + { + return true; + } + foreach (ARFNode node in nodes) + { + float nodeX = node.GetPosition().x; + float nodeY = node.GetPosition().y; + if (!SaveInfo.instance.nodePositions.ContainsKey(node.GUID)) + { + return true; + } + else + { + float dataX = SaveInfo.instance.nodePositions[node.GUID].x; + float dataY = SaveInfo.instance.nodePositions[node.GUID].y; + if ((nodeX != dataX) || (nodeY != dataY)) + { + return true; + } + } + } + foreach (ARFEdgeLink edge in edges) + { + if (!SaveInfo.instance.linkIds.Contains(edge.GUID)) + { + return true; + } + } + return false; + } + + public override List GetCompatiblePorts(Port startPort, NodeAdapter nodeAdapter) + { + var cPorts = new List(); + ports.ForEach(funcCall: port => + { + if (startPort != port && startPort.node != port.node) cPorts.Add(port); + }); + return cPorts; + } + + public void PaintWorldStorage() + { + List trackables = TrackableRequest.GetAllTrackables(worldStorageServer); + List worldAnchors = WorldAnchorRequest.GetAllWorldAnchors(worldStorageServer); + List worldLinks = WorldLinkRequest.GetAllWorldLinks(worldStorageServer); + + foreach (WorldAnchor worldAnchor in worldAnchors) + { + var waNode = new ARFNodeWorldAnchor(worldAnchor); + + Rect posTemp = new(26, 93, 160, 77); + SaveInfo.instance.nodePositions.TryGetValue(worldAnchor.UUID.ToString(), out posTemp); + waNode.SetPosition(posTemp); + + AddElement(waNode); + } + + foreach (Trackable trackable in trackables) + { + var tracknode = new ARFNodeTrackable(trackable); + + Rect posTemp = new(26, 93, 160, 77); + SaveInfo.instance.nodePositions.TryGetValue(trackable.UUID.ToString(), out posTemp); + tracknode.SetPosition(posTemp); + + AddElement(tracknode); + } + foreach (WorldLink worldLink in worldLinks) + { + var portPair = GetPortsFromWorldLink(worldLink); + ARFEdgeLink edge = portPair.Key.ConnectTo(portPair.Value); + edge.worldLink = worldLink; + edge.GUID = worldLink.UUID.ToString(); + + AddElement(edge); + } + + } + + internal ARFNodeTrackable CreateTrackableNode(Trackable track, float posX, float posY) + { + var tracknode = new ARFNodeTrackable(track); + Rect pos = new Rect(RoundToNearestHalf(posX), RoundToNearestHalf(posY), 160, 77); + tracknode.SetPosition(pos); + + AddElement(tracknode); + return tracknode; + } + + internal ARFNodeWorldAnchor CreateAnchorNode(WorldAnchor wa, float posX, float posY) + { + var waNode = new ARFNodeWorldAnchor(wa); + + Rect pos = new Rect(RoundToNearestHalf(posX), RoundToNearestHalf(posY), 160, 77); + waNode.SetPosition(pos); + + AddElement(waNode); + return waNode; + } + + internal ARFEdgeLink CreateLink(WorldLink worldLink) + { + var portPair = GetPortsFromWorldLink(worldLink); + ARFEdgeLink edge = portPair.Key.ConnectTo(portPair.Value); + edge.worldLink = worldLink; + Debug.Log(worldLink.UUID.ToString()); + edge.GUID = worldLink.UUID.ToString(); + + AddElement(edge); + return edge; + } + + public void Reload() + { + GraphEditorWindow.ResetWindow(); + DeleteElements(graphElements); + SaveInfo.instance.InitNodePos(worldStorageServer, worldStorageUser); + PaintWorldStorage(); + FrameAllElements(); + } + + public Dictionary GetNodePositions() + { + Dictionary ret = new Dictionary(); + foreach (ARFNode elem in nodes) + { + ret.Add(elem.GUID, elem.GetPosition()); + } + return ret; + } + + private KeyValuePair GetPortsFromWorldLink(WorldLink worldLink) + { + var ret = new KeyValuePair(); + + //To + Guid idTo = worldLink.UUIDTo; + Port portIn = null; + switch (worldLink.TypeTo) + { + case ObjectType.Trackable: + foreach (GraphElement node in this.graphElements) + { + ARFNodeTrackable nodeTrackable = node as ARFNodeTrackable; + if ((nodeTrackable != null) && (nodeTrackable.trackable.UUID == idTo)) + { + portIn = nodeTrackable.portIn; + break; + } + } + break; + case ObjectType.WorldAnchor: + foreach (GraphElement node in this.graphElements) + { + ARFNodeWorldAnchor nodeAnchor = node as ARFNodeWorldAnchor; + if ((nodeAnchor != null) && nodeAnchor.worldAnchor.UUID == idTo) + { + portIn = nodeAnchor.portIn; + break; + } + } + break; + default: + Debug.Log("what are you doing here..."); + break; + } + + //From + Guid idFrom = worldLink.UUIDFrom; + Port portOut = null; + switch (worldLink.TypeFrom) + { + case ObjectType.Trackable: + foreach (GraphElement node in this.graphElements) + { + ARFNodeTrackable nodeTrackable = node as ARFNodeTrackable; + if ((nodeTrackable != null) && (nodeTrackable.trackable.UUID == idFrom)) + { + portOut = nodeTrackable.portOut; + break; + } + } + break; + case ObjectType.WorldAnchor: + foreach (GraphElement node in this.graphElements) + { + ARFNodeWorldAnchor nodeAnchor = node as ARFNodeWorldAnchor; + if ((nodeAnchor != null) && nodeAnchor.worldAnchor.UUID == idFrom) + { + portOut = nodeAnchor.portOut; + break; + } + } + break; + default: + Debug.Log("what are you doing here..."); + break; + } + + if ((portOut != null) && (portIn != null)) + { + ret = new KeyValuePair(portOut, portIn); + } + + return ret; + } + + // + // Résumé : + // Calculate the rectangle size and position to fit all elements in graph. + // + // Paramètres : + // container: + // This should be the view container. + // + // Retourne : + // The calculated rectangle. + public override Rect CalculateRectToFitAll(VisualElement container) + { + Rect rectToFit = container.layout; + bool reachedFirstChild = false; + graphElements.ForEach(delegate (GraphElement ge) + { + if (!(ge is ARFEdgeLink) && !(ge is Port)) + { + if (!reachedFirstChild) + { + rectToFit = ge.ChangeCoordinatesTo(contentViewContainer, ge.contentRect); + reachedFirstChild = true; + } + else + { + rectToFit = RectUtils.Encompass(rectToFit, ge.ChangeCoordinatesTo(contentViewContainer, ge.contentRect)); + } + } + }); + return rectToFit; + } + + //k_FrameBorder is private readOnly graphView attribute, had to redeclare it to access it + private readonly int k_FrameBorder = 30; + public void FrameAllElements() + { + Vector3 frameTranslation = Vector3.zero; + Vector3 frameScaling = Vector3.one; + var rectToFit = CalculateRectToFitAll(contentViewContainer); + CalculateFrameTransform(rectToFit, layout, k_FrameBorder, out frameTranslation, out frameScaling); + Matrix4x4.TRS(frameTranslation, Quaternion.identity, frameScaling); + UpdateViewTransform(frameTranslation, frameScaling); + } + + //method to predict the position of a node (the float that will be saved in the PositionInfo singleton) + public static float RoundToNearestHalf(float a) + { + return a = Mathf.Round(a * 2f) * 0.5f; + } + + //Save all modified/deleted/added elements to the server + public void SaveInServer() + { + //DELETE ELEMENTS FROM THE SERVER + foreach (KeyValuePair elemToRemove in SaveInfo.instance.elemsToRemove) + { + string typeName = elemToRemove.Value.Name; + switch (typeName) + { + case nameof(Trackable): + TrackableRequest.DeleteTrackable(worldStorageServer, elemToRemove.Key); + break; + case nameof(WorldAnchor): + Debug.Log("delete worldanchor"); + WorldAnchorRequest.DeleteWorldAnchor(worldStorageServer, elemToRemove.Key); + break; + case nameof(WorldLink): + WorldLinkRequest.DeleteWorldLink(worldStorageServer, elemToRemove.Key); + break; + default: + Debug.Log("oops"); + break; + } + } + + //UPDATE AND ADD ELEMENTS + foreach (ARFNode node in nodes) + { + if (!SaveInfo.instance.nodePositions.ContainsKey(node.GUID)) + { + //POST TRACKABLE + if (node is ARFNodeTrackable aRFNodeTrackable) + { + var posX = new List(); + posX.Add(aRFNodeTrackable.GetPosition().x.ToString()); + var posY = new List(); + posY.Add(aRFNodeTrackable.GetPosition().y.ToString()); + Trackable trackable = aRFNodeTrackable.trackable; + trackable.KeyvalueTags["unityAuthoringPosX"] = posX; + trackable.KeyvalueTags["unityAuthoringPosY"] = posY; + String uuid = TrackableRequest.AddTrackable(worldStorageServer, trackable); + + //change the uuid in its edges, if there is a new edge to be added in the world storage it needs to have the correct uuid + uuid = uuid.Replace("\"", ""); + foreach (ARFEdgeLink edge in aRFNodeTrackable.portIn.connections) + { + edge.worldLink.UUIDTo = Guid.Parse(uuid); + } + foreach (ARFEdgeLink edge in aRFNodeTrackable.portOut.connections) + { + edge.worldLink.UUIDFrom = Guid.Parse(uuid); + } + aRFNodeTrackable.trackable.UUID = Guid.Parse(uuid); + aRFNodeTrackable.GUID = uuid; + aRFNodeTrackable.title = trackable.Name; + } + //POST WORLDANCHOR + if (node is ARFNodeWorldAnchor aRFNodeWorldAnchor) + { + var posX = new List(); + posX.Add(aRFNodeWorldAnchor.GetPosition().x.ToString()); + var posY = new List(); + posY.Add(aRFNodeWorldAnchor.GetPosition().y.ToString()); + WorldAnchor worldAnchor = aRFNodeWorldAnchor.worldAnchor; + worldAnchor.KeyvalueTags["unityAuthoringPosX"] = posX; + worldAnchor.KeyvalueTags["unityAuthoringPosY"] = posY; + + String uuid = WorldAnchorRequest.AddWorldAnchor(worldStorageServer, worldAnchor); + + //change the uuid in its edges, if there is a new edge to be added in the world storage it needs to have the correct uuid + uuid = uuid.Replace("\"",""); + foreach (ARFEdgeLink edge in aRFNodeWorldAnchor.portIn.connections) + { + edge.worldLink.UUIDTo = Guid.Parse(uuid); + } + foreach (ARFEdgeLink edge in aRFNodeWorldAnchor.portOut.connections) + { + edge.worldLink.UUIDFrom = Guid.Parse(uuid); + } + aRFNodeWorldAnchor.worldAnchor.UUID = Guid.Parse(uuid); + aRFNodeWorldAnchor.GUID = uuid; + aRFNodeWorldAnchor.title = worldAnchor.Name; + } + } + else + { + float xLocal = node.GetPosition().x; + float yLocal = node.GetPosition().y; + float xServer = SaveInfo.instance.nodePositions[node.GUID].x; ; + float yServer = SaveInfo.instance.nodePositions[node.GUID].y; + if (((xLocal != xServer) || (yLocal != yServer)) || SaveInfo.instance.elemsToUpdate.Contains(node.GUID)) + { + if(node is ARFNodeTrackable aRFNodeTrackable) + { + var posX = new List(); + posX.Add(aRFNodeTrackable.GetPosition().x.ToString()); + var posY = new List(); + posY.Add(aRFNodeTrackable.GetPosition().y.ToString()); + Trackable trackable = aRFNodeTrackable.trackable; + trackable.KeyvalueTags["unityAuthoringPosX"] = posX; + trackable.KeyvalueTags["unityAuthoringPosY"] = posY; + TrackableRequest.UpdateTrackable(worldStorageServer, trackable); + aRFNodeTrackable.title = trackable.Name; + } + if (node is ARFNodeWorldAnchor aRFNodeWorldAnchor) + { + var posX = new List(); + posX.Add(aRFNodeWorldAnchor.GetPosition().x.ToString()); + var posY = new List(); + posY.Add(aRFNodeWorldAnchor.GetPosition().y.ToString()); + WorldAnchor worldAnchor = aRFNodeWorldAnchor.worldAnchor; + worldAnchor.KeyvalueTags["unityAuthoringPosX"] = posX; + worldAnchor.KeyvalueTags["unityAuthoringPosY"] = posY; + WorldAnchorRequest.UpdateWorldAnchor(worldStorageServer, worldAnchor); + aRFNodeWorldAnchor.title = worldAnchor.Name; + } + } + } + node.MarkSaved(); + } + foreach (ARFEdgeLink edge in edges) + { + if (edge is ARFEdgeLink aRFEdgeLink) + { + if (!SaveInfo.instance.linkIds.Contains(aRFEdgeLink.GUID)) + { + WorldLink worldLink = aRFEdgeLink.worldLink; + string uuid = WorldLinkRequest.AddWorldLink(worldStorageServer, worldLink); + uuid = uuid.Replace("\"", ""); + + aRFEdgeLink.worldLink.UUID = Guid.Parse(uuid); + aRFEdgeLink.GUID = uuid; + } + else if (SaveInfo.instance.elemsToUpdate.Contains(aRFEdgeLink.GUID)) + { + WorldLink worldLink = aRFEdgeLink.worldLink; + WorldLinkRequest.UpdateWorldLink(worldStorageServer, worldLink); + } + aRFEdgeLink.MarkSaved(); + } + } + SaveInfo.instance.InitNodePos(worldStorageServer, worldStorageUser); + + GraphEditorWindow.ResetWindow(); + } + } } \ No newline at end of file diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNode.cs b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNode.cs index 5ea6fbedc22f6960cbdacd0e2766c59bce8ed992..529db0ccef24612a429fa8300f594abadfb1649f 100644 --- a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNode.cs +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNode.cs @@ -1,41 +1,144 @@ -// -// ARF - Augmented Reality Framework (ETSI ISG ARF) -// -// Copyright 2022 ETSI -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Last change: June 2022 -// - -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UIElements; -using UnityEditor.Experimental.GraphView; - -namespace ETSI.ARF.WorldStorage.UI -{ - public class ARFNode : Node - { - public string GUID; - public string text; - public bool entryPoint = false; - - public ARFNode() - { - - - } - } +// +// ARF - Augmented Reality Framework (ETSI ISG ARF) +// +// Copyright 2022 ETSI +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Last change: July 2022 +// + +#define USING_OPENAPI_GENERATOR // alt. is Swagger + +using UnityEditor; + +#if USING_OPENAPI_GENERATOR +using Org.OpenAPITools.Model; +#else +using IO.Swagger.Api; +using IO.Swagger.Model; +#endif +using UnityEngine.UIElements; +using UnityEditor.Experimental.GraphView; +using Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Graph; +using System; +using UnityEngine; + +namespace ETSI.ARF.WorldStorage.UI +{ + public abstract class ARFNode : Node + { + public string GUID; + public bool entryPoint = false; + public ARFPort portOut; + public ARFPort portIn; + public GUID id; + + public Image savedIcon; + + public ARFNode() + { + } + public override Port InstantiatePort(Orientation orientation, Direction direction, Port.Capacity capacity, Type type) + { + switch (direction) + { + case Direction.Input: + portIn = ARFPort.CreateARF(orientation, direction, capacity, type); + return portIn; + case Direction.Output: + portOut = ARFPort.CreateARF(orientation, direction, capacity, type); + return portOut; + default: + return null; + } + } + + public void DisconnectAllPorts(ARFGraphView graphView) + { + DisconnectInputPorts(graphView); + DisconnectOutputPorts(graphView); + } + + private void DisconnectInputPorts(ARFGraphView graphView) + { + DisconnectPorts(inputContainer, graphView); + } + + private void DisconnectOutputPorts(ARFGraphView graphView) + { + DisconnectPorts(outputContainer, graphView); + } + + private void DisconnectPorts(VisualElement container, ARFGraphView graphView) + { + foreach (Port port in container.Children()) + { + if (!port.connected) + { + continue; + } + + graphView.DeleteElements(port.connections); + } + } + + public Port GeneratePort(ARFNode node, Direction portDirection, Port.Capacity capacity = Port.Capacity.Multi) + { + return node.InstantiatePort(Orientation.Horizontal, portDirection, capacity, typeof(int)); // dummy + } + + //override the BuildContextualMenu method to prevent the "disconnect" option from appearing in the contextual menu + public override void BuildContextualMenu(ContextualMenuPopulateEvent evt) + { + } + + public abstract ObjectType GetElemType(); + public void MarkUnsaved() + { + if(savedIcon == null) + { + //the icon to add if the node does not correspond to an element in the server + Texture2D warningImage = (Texture2D)AssetDatabase.LoadAssetAtPath("Assets/ETSI.ARF/ARF World Storage API/Images/cloud.png", typeof(Texture2D)); + savedIcon = new Image + { + image = warningImage, + scaleMode = ScaleMode.ScaleToFit + }; + savedIcon.style.width = 25; + savedIcon.style.height = 25; + savedIcon.style.minWidth = 25; + savedIcon.style.minHeight = 25; + savedIcon.style.left = 8; + savedIcon.style.paddingRight = 8; + savedIcon.style.alignSelf = Align.Center; + + } + if (!titleContainer.Contains(savedIcon)) + { + titleContainer.Insert(0,savedIcon); + } + tooltip = "This element is not synchronized with the World Storage"; + } + + public void MarkSaved() + { + if (titleContainer.Contains(savedIcon)) + { + titleContainer.Remove(savedIcon); + tooltip = ""; + } + } + + } } \ No newline at end of file diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNodeTrackable.cs b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNodeTrackable.cs new file mode 100644 index 0000000000000000000000000000000000000000..4aed9914d9c403438cf7f639e53f612fb9d73b09 --- /dev/null +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNodeTrackable.cs @@ -0,0 +1,90 @@ +// +// ARF - Augmented Reality Framework (ETSI ISG ARF) +// +// Copyright 2022 ETSI +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Last change: July 2022 +// + +#define USING_OPENAPI_GENERATOR // alt. is Swagger + +using UnityEngine; + +#if USING_OPENAPI_GENERATOR +using Org.OpenAPITools.Model; +#else +using IO.Swagger.Api; +using IO.Swagger.Model; +#endif +using UnityEngine.UIElements; +using UnityEditor.Experimental.GraphView; +using Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Windows; +using UnityEditor; + +namespace ETSI.ARF.WorldStorage.UI +{ + public class ARFNodeTrackable : ARFNode + { + public Trackable trackable; + + public ARFNodeTrackable(Trackable trackable) + { + this.trackable = trackable; + this.GUID = trackable.UUID.ToString(); + this.title = trackable.Name; + + /*COLOR*/ + var colorRectangle = new VisualElement(); + colorRectangle.style.height = 160; + colorRectangle.style.height = 5; + colorRectangle.style.backgroundColor = new Color(1, 0.31f, 0.31f, 0.9f); + //get the index of the title container + int titleIndex = mainContainer.hierarchy.IndexOf(titleContainer); + mainContainer.Insert(titleIndex+1, colorRectangle); + + /*PORTS*/ + var portIn = GeneratePort(this, Direction.Input, Port.Capacity.Multi); + portIn.portColor = new Color(0.66f, 0.39f, 1, 0.77f); + portIn.portName = "Target"; // "Input" + //portIn.AddManipulator(new EdgeConnector(new WorldLinkListener())); + inputContainer.Add(portIn); + + var portOut = GeneratePort(this, Direction.Output, Port.Capacity.Multi); + portOut.portColor = new Color(0.66f, 0.39f, 1, 0.77f); + portOut.portName = "Source"; // "Output"; + //portOut.AddManipulator(new EdgeConnector(new WorldLinkListener())); ; + outputContainer.Add(portOut); + + RefreshExpandedState(); + RefreshPorts(); + + /*MANIPULATOR*/ + var doubleClickManipulator = new Clickable(Clicked); + doubleClickManipulator.activators.Clear(); + doubleClickManipulator.activators.Add(new ManipulatorActivationFilter { button = MouseButton.LeftMouse, clickCount = 2 }); + this.AddManipulator(doubleClickManipulator); + } + + public void Clicked() + { + Debug.Log(trackable.ToJson()); + GraphEditorWindow.ShowWindow(this); + } + public override ObjectType GetElemType() + { + return ObjectType.Trackable; + } + } +} \ No newline at end of file diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNodeTrackable.cs.meta b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNodeTrackable.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..17e98f27c0df67b74d8e87e243203ba56f30d987 --- /dev/null +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNodeTrackable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 01bfb1a0a4a788c48a6c6675034ba8d5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNodeWorldAnchor.cs b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNodeWorldAnchor.cs new file mode 100644 index 0000000000000000000000000000000000000000..e5250b4b1c363f266e378b71c315cdc99f00db02 --- /dev/null +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNodeWorldAnchor.cs @@ -0,0 +1,86 @@ +// +// ARF - Augmented Reality Framework (ETSI ISG ARF) +// +// Copyright 2022 ETSI +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Last change: July 2022 +// + +#define USING_OPENAPI_GENERATOR // alt. is Swagger + +using UnityEngine; + +#if USING_OPENAPI_GENERATOR +using Org.OpenAPITools.Model; +#else +using IO.Swagger.Api; +using IO.Swagger.Model; +#endif +using UnityEngine.UIElements; +using UnityEditor.Experimental.GraphView; +using Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Windows; + +namespace ETSI.ARF.WorldStorage.UI +{ + public class ARFNodeWorldAnchor : ARFNode + { + public WorldAnchor worldAnchor; + + public ARFNodeWorldAnchor(WorldAnchor worldAnchor) + { + this.worldAnchor = worldAnchor; + this.GUID = worldAnchor.UUID.ToString(); + this.title = worldAnchor.Name; + + /*COLOR*/ + var colorRectangle = new VisualElement(); + colorRectangle.style.height = 160; + colorRectangle.style.height = 5; + colorRectangle.style.backgroundColor = new Color(1, 0.7f, 0, 0.9f); + mainContainer.Insert(1, colorRectangle); + + /*PORTS*/ + var portIn = GeneratePort(this, Direction.Input, Port.Capacity.Multi); + portIn.portColor = new Color(0.66f, 0.39f, 1, 0.77f); + portIn.portName = "Target"; // "Input"; + //portIn.AddManipulator(new EdgeConnector(new WorldLinkListener())); + inputContainer.Add(portIn); + + var portOut = GeneratePort(this, Direction.Output, Port.Capacity.Multi); + portOut.portColor = new Color(0.66f, 0.39f, 1, 0.77f); + portOut.portName = "Source"; // "Output"; + //portOut.AddManipulator(new EdgeConnector(new WorldLinkListener())); + outputContainer.Add(portOut); + + RefreshExpandedState(); + RefreshPorts(); + + /*MANIPULATOR*/ + var doubleClickManipulator = new Clickable(Clicked); + doubleClickManipulator.activators.Clear(); + doubleClickManipulator.activators.Add(new ManipulatorActivationFilter { button = MouseButton.LeftMouse, clickCount = 2 }); + this.AddManipulator(doubleClickManipulator); + } + + public void Clicked() + { + GraphEditorWindow.ShowWindow(this); + } + public override ObjectType GetElemType() + { + return ObjectType.WorldAnchor; + } + } +} \ No newline at end of file diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNodeWorldAnchor.cs.meta b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNodeWorldAnchor.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..bb1bb7e9dbcc846457423ce25bb5ae3dccc979ec --- /dev/null +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFNodeWorldAnchor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 21e22c1ed011b7a4da95fad83be1d9fa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFPort.cs b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFPort.cs new file mode 100644 index 0000000000000000000000000000000000000000..20852ea13231cd633daf4f3c407efef73fafe5e0 --- /dev/null +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFPort.cs @@ -0,0 +1,69 @@ +// +// ARF - Augmented Reality Framework (ETSI ISG ARF) +// +// Copyright 2022 ETSI +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Last change: July 2022 +// + +using Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Windows; +using ETSI.ARF.WorldStorage.UI; +using Org.OpenAPITools.Model; +using System; +using System.Collections.Generic; +using UnityEditor.Experimental.GraphView; +using UnityEngine; +using UnityEngine.UIElements; + +namespace Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Graph +{ + public class ARFPort : Port + { + protected ARFPort(Orientation portOrientation, Direction portDirection, Capacity portCapacity, Type type) : base(portOrientation, portDirection, portCapacity, type) + { + } + + public override void Connect(Edge edge) + { + base.Connect(edge); + ARFNode fromNode = edge.output.node as ARFNode; + ARFNode toNode = edge.input.node as ARFNode; + + if (edge is ARFEdgeLink aRFedge) + { + List transform = new List(); + for (int i = 0; i < 15; i++) + { + transform.Add(0); + } + transform.Add(1); + + WorldLink worldLink = new(Guid.NewGuid(), Guid.Parse(SaveInfo.instance.worldStorageUser.UUID), Guid.Parse(fromNode.GUID), Guid.Parse(toNode.GUID), fromNode.GetElemType(), toNode.GetElemType(), transform, UnitSystem.CM, new Dictionary>()); + aRFedge.worldLink = worldLink; + } + } + + public static ARFPort CreateARF(Orientation orientation, Direction direction, Capacity capacity, Type type) where TEdge : Edge, new() + { + WorldLinkListener listener = new WorldLinkListener(); + ARFPort port = new(orientation, direction, capacity, type) + { + m_EdgeConnector = new EdgeConnector(listener) + }; + port.AddManipulator(port.m_EdgeConnector); + return port; + } + } +} \ No newline at end of file diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFPort.cs.meta b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFPort.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..6d043fde500829981fc15944de7d1198cb5e1375 --- /dev/null +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/ARFPort.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3c67fa4402011954bb65be6215d52512 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/GraphWindow.cs b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/GraphWindow.cs deleted file mode 100644 index 3a21abee031ab83a53c4735195847331fa312a85..0000000000000000000000000000000000000000 --- a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/GraphWindow.cs +++ /dev/null @@ -1,216 +0,0 @@ -// -// ARF - Augmented Reality Framework (ETSI ISG ARF) -// -// Copyright 2022 ETSI -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Last change: June 2022 -// - -#define USING_OPENAPI_GENERATOR // alt. is Swagger - -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using UnityEditor; -using UnityEditor.Experimental.GraphView; -using UnityEngine.UIElements; -using UnityEditor.UIElements; -using ETSI.ARF.WorldStorage.REST; - -#if USING_OPENAPI_GENERATOR -using Org.OpenAPITools.Api; -using Org.OpenAPITools.Model; -#else -using IO.Swagger.Api; -using IO.Swagger.Model; -#endif - - -namespace ETSI.ARF.WorldStorage.UI -{ - - public class GraphWindow : EditorWindow - { - [HideInInspector] public WorldStorageServer worldStorageSettings; - - [SerializeField] public List trackables = new List(); - - bool groupEnabled; - - string uid = System.Guid.Empty.ToString(); - string customName = "NotDefined"; - string creatorUid = System.Guid.Empty.ToString(); - string type = "Unknow"; - string unit = "Unknow"; - Vector2Int dim; - - private Trackable currentTrackable; - private Vector2 scrollPos; - private Color ori; - private GUIStyle gsTest; - - private ARFGraphView myGraph; - - [MenuItem("ARFWorldStorage/Graph Editor")] - public static void ShowWindow()//WorldStorageServer ws) - { - GraphWindow win = EditorWindow.GetWindow(typeof(GraphWindow), false, WorldStorageWindow.winName) as GraphWindow; - //win.worldStorageSettings = ws; - } - - public GraphWindow() - { - // init somne stuffs - //currentTrackable = new Trackable(); - } - - public void OnEnable() - { - ConstructGraphView(); - GenerateToolbar(); - } - - public void OnDisable() - { - rootVisualElement.Remove(myGraph); - } - - private void GenerateToolbar() - { - var toolbar = new Toolbar(); - - var createNodeT = new Button(clickEvent: () => { myGraph.CreateNode("Trackable"); }); - createNodeT.text = "Create Trackable"; - toolbar.Add(createNodeT); - - var createNodeWA = new Button(clickEvent: () => { myGraph.CreateNode("World Anchor"); }); - createNodeWA.text = "Create World Anchor"; - toolbar.Add(createNodeWA); - - var createNodeL = new Button(clickEvent: () => { }); - createNodeL.text = "Create Link"; - toolbar.Add(createNodeL); - - var close = new Button(clickEvent: () => { Close(); }); - close.text = "Close Window"; - toolbar.Add(close); - - rootVisualElement.Add(toolbar); - } - - private void ConstructGraphView() - { - myGraph = new ARFGraphView - { - name = "ARF Graph" - }; - myGraph.StretchToParentSize(); - //myGraph.StretchToParentWidth(); - rootVisualElement.Add(myGraph); - } - - void OnGUI() - { - ori = GUI.backgroundColor; // remember ori color - - gsTest = new GUIStyle("window"); - gsTest.normal.textColor = WorldStorageWindow.arfColors[0]; - gsTest.fontStyle = FontStyle.Bold; - - EditorGUILayout.Space(24); - GUI.contentColor = WorldStorageWindow.arfColors[1]; - WorldStorageWindow.DrawCopyright(); - - //TLP.Editor.EditorGraph graph = new TLP.Editor.EditorGraph(0, -1, 10, 1, "Just a sin wave", 100); - //graph.AddFunction(x => Mathf.Sin(x)); - //graph.Draw(); - } - - /* - void DrawTrackableStuffs()// Trackable trackable) - { - GUILayout.BeginVertical("AR Trackable", gsTest); - // - GUILayout.Label("Server: " + worldStorageSettings.serverName, EditorStyles.whiteLargeLabel); - GUILayout.Label("Creator UID: " + creatorUid, EditorStyles.miniLabel); // readonly - EditorGUILayout.Space(); - - //GUILayout.BeginHorizontal(); - uid = EditorGUILayout.TextField("UID (0 = new one)", uid); - EditorGUILayout.Space(); - - GUI.backgroundColor = WorldStorageWindow.arfColors[1]; - if (GUILayout.Button("Get Parameters")) - { - Trackable t = RESTfulTrackableRequest.GetTrackable(worldStorageSettings, uid); - creatorUid = t.CreatorUUID.ToString(); - type = t.GetType().ToString(); - unit = t.Unit.ToString(); - } - GUI.backgroundColor = ori; - - type = EditorGUILayout.TextField("Trackable Type", type); - unit = EditorGUILayout.TextField("Unit System", unit); - - EditorGUILayout.Space(10); - dim = EditorGUILayout.Vector2IntField("Dimension", dim); - - EditorGUILayout.Space(); - GUILayout.Button("Payload from Asset..."); - - EditorGUILayout.Space(); - groupEnabled = EditorGUILayout.BeginToggleGroup("Optional Parameters:", groupEnabled); - EditorGUILayout.IntField("Number of KeyValues", 0); - EditorGUILayout.Space(); - EditorGUILayout.TextField("Key", ""); - EditorGUILayout.TextField("Value", ""); - EditorGUILayout.EndToggleGroup(); - // - GUILayout.EndVertical(); - - GUI.backgroundColor = WorldStorageWindow.arfColors[3]; - if (GUILayout.Button("Delete Trackable")) - { - Debug.Log("Deleting Trackable"); - RESTfulTrackableRequest.DeleteTrackable(worldStorageSettings, uid); - uid = System.Guid.Empty.ToString(); - creatorUid = System.Guid.Empty.ToString(); - type = ""; - unit = ""; - WorldStorageWindow.WorldStorageWindowSingleton.UpdateList(); - WorldStorageWindow.WorldStorageWindowSingleton.Repaint(); - } - GUI.backgroundColor = ori; - - GUI.backgroundColor = WorldStorageWindow.arfColors[2]; - if (GUILayout.Button("Create/Update Trackable")) - { - Debug.Log("PostAddTrackable"); - if (string.IsNullOrEmpty(uid) || uid == "0") uid = System.Guid.Empty.ToString(); - Trackable t = RESTfulTrackableRequest.TrackableFromStrings(uid, cus, worldStorageSettings.creatorUID); - RESTfulTrackableRequest.PostAddTrackable(worldStorageSettings, t); - WorldStorageWindow.WorldStorageWindowSingleton.UpdateList(); - WorldStorageWindow.WorldStorageWindowSingleton.Repaint(); - - uid = t.UUID.ToString(); - type = t.GetType().ToString(); - unit = t.Unit.ToString(); - } - GUI.backgroundColor = ori; - } - - */ - } -} \ No newline at end of file diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/WorldLinkListener.cs b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/WorldLinkListener.cs new file mode 100644 index 0000000000000000000000000000000000000000..d0103cf592b40f607ac39b8c50acd8b065e5809f --- /dev/null +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/WorldLinkListener.cs @@ -0,0 +1,98 @@ +// +// ARF - Augmented Reality Framework (ETSI ISG ARF) +// +// Copyright 2022 ETSI +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Last change: July 2022 +// + +using Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Windows; +using System.Collections.Generic; +using UnityEditor.Experimental.GraphView; +using UnityEngine; +using static UnityEditor.Experimental.GraphView.Port; + +namespace Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Graph +{ + public class WorldLinkListener : IEdgeConnectorListener + { + private GraphViewChange m_GraphViewChange; + + private List m_EdgesToCreate; + + private List m_EdgesToDelete; + + public WorldLinkListener() + { + m_EdgesToCreate = new List(); + m_EdgesToDelete = new List(); + m_GraphViewChange.edgesToCreate = m_EdgesToCreate; + } + public void OnDrop(GraphView graphView, Edge edge) + { + m_EdgesToCreate.Clear(); + m_EdgesToCreate.Add(edge); + m_EdgesToDelete.Clear(); + if (edge.input.capacity == Capacity.Single) + { + foreach (Edge connection in edge.input.connections) + { + if (connection != edge) + { + m_EdgesToDelete.Add(connection); + } + } + } + + if (edge.output.capacity == Capacity.Single) + { + foreach (Edge connection2 in edge.output.connections) + { + if (connection2 != edge) + { + m_EdgesToDelete.Add(connection2); + } + } + } + + if (m_EdgesToDelete.Count > 0) + { + graphView.DeleteElements(m_EdgesToDelete); + } + + List edgesToCreate = m_EdgesToCreate; + if (graphView.graphViewChanged != null) + { + edgesToCreate = graphView.graphViewChanged(m_GraphViewChange).edgesToCreate; + } + + foreach (Edge item in edgesToCreate) + { + graphView.AddElement(item); + edge.input.Connect(item); + edge.output.Connect(item); + } + if (!SaveInfo.instance.linkIds.Contains(((ARFEdgeLink)edge).GUID)) + { + ((ARFEdgeLink)edge).MarkUnsaved(); + } + GraphEditorWindow.ShowWindow((ARFEdgeLink)edge); + } + + public void OnDropOutsidePort(Edge edge, Vector2 position) + { + } + } +} \ No newline at end of file diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/WorldLinkListener.cs.meta b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/WorldLinkListener.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..e19f2ea2695b2106e4290577b9abef17cb4dd141 --- /dev/null +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Graph/WorldLinkListener.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 54dbfcfdc75de1b46bc7da09df52db34 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/GraphEditorWindow.cs b/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/GraphEditorWindow.cs new file mode 100644 index 0000000000000000000000000000000000000000..265e3814e87727711b7c9e4bcc3758c01afbb9e4 --- /dev/null +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/GraphEditorWindow.cs @@ -0,0 +1,1213 @@ +// +// ARF - Augmented Reality Framework (ETSI ISG ARF) +// +// Copyright 2022 ETSI +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Last change: July 2022 +// + +using Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Graph; +using ETSI.ARF.WorldStorage.REST; +using ETSI.ARF.WorldStorage.UI; +using Org.OpenAPITools.Model; +using System; +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; + +namespace Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Windows +{ + public class GraphEditorWindow : EditorWindow + { + public enum GraphEditorType + { + TRACKABLE, + WORLDANCHOR, + WORLDLINK, + NULL + } + + public GraphEditorType type; + + public ARFNodeTrackable trackableNode; + public ARFNodeWorldAnchor worldAnchorNode; + public ARFEdgeLink worldLinkEdge; + + public Trackable trackable; + public WorldAnchor worldAnchor; + public WorldLink worldLink; + + public Vector3 local_size; + public Vector3 local_rot; + public Vector3 local_pos; + + //test + string m_newKey = ""; + List m_newValues = new List(); + + // UI stuffs + private Vector2 scrollPos; + static public GraphEditorWindow winSingleton; + + public void OnEnable() + { + ResetWindow(); + } + + public static void ResetWindow() + { + Type inspectorType = Type.GetType("UnityEditor.InspectorWindow,UnityEditor.dll"); + winSingleton = GetWindow("Element Editor", true, inspectorType); + winSingleton.trackable = null; + winSingleton.worldAnchor = null; + winSingleton.worldLink = null; + + winSingleton.trackableNode = null; + winSingleton.worldAnchorNode = null; + winSingleton.worldLinkEdge = null; + + winSingleton.local_size = Vector3.zero; + winSingleton.local_rot = Vector3.zero; + winSingleton.local_pos = Vector3.zero; + + winSingleton.type = GraphEditorType.NULL; + } + + public static void ShowWindow(ARFNodeTrackable trackableNode) + { + Type inspectorType = Type.GetType("UnityEditor.InspectorWindow,UnityEditor.dll"); + winSingleton = GetWindow("Element Editor", true, inspectorType); + winSingleton.type = GraphEditorType.TRACKABLE; + + winSingleton.trackable = null; + winSingleton.worldAnchor = null; + winSingleton.worldLink = null; + + winSingleton.trackableNode = null; + winSingleton.worldAnchorNode = null; + winSingleton.worldLinkEdge = null; + + winSingleton.trackableNode = trackableNode; + winSingleton.trackable = trackableNode.trackable; + + winSingleton.local_size = new Vector3((float)winSingleton.trackable.TrackableSize[0], (float)winSingleton.trackable.TrackableSize[1], (float)winSingleton.trackable.TrackableSize[2]); + if (winSingleton.trackable.LocalCRS.Count == 16) + { + Matrix4x4 localCRS = new Matrix4x4(); + localCRS.m00 = winSingleton.trackable.LocalCRS[0]; localCRS.m01 = winSingleton.trackable.LocalCRS[1]; localCRS.m02 = winSingleton.trackable.LocalCRS[2]; localCRS.m03 = winSingleton.trackable.LocalCRS[3]; + localCRS.m10 = winSingleton.trackable.LocalCRS[4]; localCRS.m11 = winSingleton.trackable.LocalCRS[5]; localCRS.m12 = winSingleton.trackable.LocalCRS[6]; localCRS.m13 = winSingleton.trackable.LocalCRS[7]; + localCRS.m20 = winSingleton.trackable.LocalCRS[8]; localCRS.m21 = winSingleton.trackable.LocalCRS[9]; localCRS.m22 = winSingleton.trackable.LocalCRS[10]; localCRS.m23 = winSingleton.trackable.LocalCRS[11]; + localCRS.m30 = winSingleton.trackable.LocalCRS[12]; localCRS.m31 = winSingleton.trackable.LocalCRS[13]; localCRS.m32 = winSingleton.trackable.LocalCRS[14]; localCRS.m33 = winSingleton.trackable.LocalCRS[15]; + winSingleton.local_pos = localCRS.GetPosition(); + winSingleton.local_rot = localCRS.rotation.eulerAngles; + } + + } + + public static void ShowWindow(ARFNodeWorldAnchor worldAnchorNode) + { + Type inspectorType = Type.GetType("UnityEditor.InspectorWindow,UnityEditor.dll"); + winSingleton = GetWindow("Element Editor", true, inspectorType); + winSingleton.type = GraphEditorType.WORLDANCHOR; + + winSingleton.trackable = null; + winSingleton.worldAnchor = null; + winSingleton.worldLink = null; + + winSingleton.trackableNode = null; + winSingleton.worldAnchorNode = null; + winSingleton.worldLinkEdge = null; + + winSingleton.worldAnchorNode = worldAnchorNode; + winSingleton.worldAnchor = worldAnchorNode.worldAnchor; + + winSingleton.local_size = new Vector3((float)winSingleton.worldAnchor.WorldAnchorSize[0], (float)winSingleton.worldAnchor.WorldAnchorSize[1], (float)winSingleton.worldAnchor.WorldAnchorSize[2]); + if (winSingleton.worldAnchor.LocalCRS.Count == 16) + { + Matrix4x4 localCRS = new Matrix4x4(); + localCRS.m00 = winSingleton.worldAnchor.LocalCRS[0]; localCRS.m01 = winSingleton.worldAnchor.LocalCRS[1]; localCRS.m02 = winSingleton.worldAnchor.LocalCRS[2]; localCRS.m03 = winSingleton.worldAnchor.LocalCRS[3]; + localCRS.m10 = winSingleton.worldAnchor.LocalCRS[4]; localCRS.m11 = winSingleton.worldAnchor.LocalCRS[5]; localCRS.m12 = winSingleton.worldAnchor.LocalCRS[6]; localCRS.m13 = winSingleton.worldAnchor.LocalCRS[7]; + localCRS.m20 = winSingleton.worldAnchor.LocalCRS[8]; localCRS.m21 = winSingleton.worldAnchor.LocalCRS[9]; localCRS.m22 = winSingleton.worldAnchor.LocalCRS[10]; localCRS.m23 = winSingleton.worldAnchor.LocalCRS[11]; + localCRS.m30 = winSingleton.worldAnchor.LocalCRS[12]; localCRS.m31 = winSingleton.worldAnchor.LocalCRS[13]; localCRS.m32 = winSingleton.worldAnchor.LocalCRS[14]; localCRS.m33 = winSingleton.worldAnchor.LocalCRS[15]; + winSingleton.local_pos = localCRS.GetPosition(); + winSingleton.local_rot = localCRS.rotation.eulerAngles; + } + } + + public static void ShowWindow(ARFEdgeLink graphEdge) + { + Type inspectorType = Type.GetType("UnityEditor.InspectorWindow,UnityEditor.dll"); + winSingleton = GetWindow("Element Editor", true, inspectorType); + winSingleton.type = GraphEditorType.WORLDLINK; + + winSingleton.trackable = null; + winSingleton.worldAnchor = null; + winSingleton.worldLink = null; + + winSingleton.trackableNode = null; + winSingleton.worldAnchorNode = null; + winSingleton.worldLinkEdge = null; + + winSingleton.worldLinkEdge = graphEdge; + winSingleton.worldLink = graphEdge.worldLink; + + if (winSingleton.worldLink.Transform.Count == 16) + { + Matrix4x4 localCRS = new Matrix4x4(); + localCRS.m00 = winSingleton.worldLink.Transform[0]; localCRS.m01 = winSingleton.worldLink.Transform[1]; localCRS.m02 = winSingleton.worldLink.Transform[2]; localCRS.m03 = winSingleton.worldLink.Transform[3]; + localCRS.m10 = winSingleton.worldLink.Transform[4]; localCRS.m11 = winSingleton.worldLink.Transform[5]; localCRS.m12 = winSingleton.worldLink.Transform[6]; localCRS.m13 = winSingleton.worldLink.Transform[7]; + localCRS.m20 = winSingleton.worldLink.Transform[8]; localCRS.m21 = winSingleton.worldLink.Transform[9]; localCRS.m22 = winSingleton.worldLink.Transform[10]; localCRS.m23 = winSingleton.worldLink.Transform[11]; + localCRS.m30 = winSingleton.worldLink.Transform[12]; localCRS.m31 = winSingleton.worldLink.Transform[13]; localCRS.m32 = winSingleton.worldLink.Transform[14]; localCRS.m33 = winSingleton.worldLink.Transform[15]; + winSingleton.local_pos = localCRS.GetPosition(); + winSingleton.local_rot = localCRS.rotation.eulerAngles; + } + } + + public void OnGUI() + { + scrollPos = EditorGUILayout.BeginScrollView(scrollPos, GUILayout.ExpandWidth(true)); + + //style for copyrights label (left aligned) + var leftStyle = GUI.skin.GetStyle("Label"); + leftStyle.alignment = TextAnchor.UpperLeft; + + GUILayout.Label("Augmented Reality Framework", leftStyle); + GUILayout.Label("Copyright (C) 2022, ETSI (BSD 3-Clause License)", leftStyle); + + + switch (type) + { + case GraphEditorType.WORLDLINK: + BuildWorldLinkUI(); + break; + case GraphEditorType.TRACKABLE: + BuildTrackableUI(); + break; + case GraphEditorType.WORLDANCHOR: + BuildWorldAnchorUI(); + break; + default: + break; + } + + EditorGUILayout.EndScrollView(); + } + + //BUILD UI FOR MODIYING THE WORLDANCHOR + private void BuildWorldAnchorUI() + { + if(worldAnchor != null) { + + // + //HEADER + // + + //anchor icon + EditorGUILayout.BeginHorizontal(); + Texture anchorImage = (Texture)AssetDatabase.LoadAssetAtPath("Assets/ETSI.ARF/ARF World Storage API/Images/anchor.png", typeof(Texture)); + GUI.backgroundColor = Color.clear; + GUILayout.Box(anchorImage, GUILayout.Width(40), GUILayout.Height(40)); + + //anchor label + EditorGUILayout.BeginVertical(GUILayout.Height(50)); + GUILayout.FlexibleSpace(); + EditorGUILayout.LabelField("WORLD ANCHOR", EditorStyles.boldLabel); + GUILayout.FlexibleSpace(); + EditorGUILayout.EndVertical(); + EditorGUILayout.EndHorizontal(); + + //separator line + var rect = EditorGUILayout.BeginHorizontal(GUILayout.Height(10)); + DrawUILine(new Color(1, 0.7f, 0, 0.9f), 5, 5); + EditorGUILayout.EndHorizontal(); + + if (worldAnchorNode.titleContainer.Contains(worldAnchorNode.savedIcon)) + { + //the icon to add if the node does not correspond to an element in the server + Texture2D warningImage = (Texture2D)AssetDatabase.LoadAssetAtPath("Assets/ETSI.ARF/ARF World Storage API/Images/warning.png", typeof(Texture2D)); + + GUI.backgroundColor = Color.clear; + GUILayout.BeginHorizontal(); + GUILayout.Box(warningImage, GUILayout.Width(27), GUILayout.Height(27)); + EditorGUILayout.LabelField("This element is not synchronized with the World Storage"); + GUILayout.EndHorizontal(); + } + + // + //ELEMENT PARAMETERS + // + + EditorGUI.BeginChangeCheck(); + + //uuid + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("UUID ", EditorStyles.boldLabel, GUILayout.Width(50)); + if (!SaveInfo.instance.nodePositions.ContainsKey(worldAnchor.UUID.ToString())) + { + EditorGUILayout.LabelField("none yet (element not yet saved in the server)"); + } + else + { + EditorGUILayout.SelectableLabel(worldAnchor.UUID.ToString(), EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight)); + } + EditorGUILayout.EndHorizontal(); + + //name + EditorGUILayout.BeginHorizontal(); + EditorGUI.BeginChangeCheck(); + EditorGUILayout.LabelField("Name ", EditorStyles.boldLabel, GUILayout.Width(50)); + worldAnchor.Name = EditorGUILayout.DelayedTextField(worldAnchor.Name); + if (EditorGUI.EndChangeCheck()) + { + worldAnchorNode.title = worldAnchor.Name; + } + EditorGUILayout.EndHorizontal(); + + //unit system + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Unit ", EditorStyles.boldLabel, GUILayout.Width(50)); + worldAnchor.Unit = (UnitSystem)EditorGUILayout.EnumPopup(worldAnchor.Unit); + EditorGUILayout.EndHorizontal(); + + //style for sublabels (right aligned) + var rightStyle = GUI.skin.GetStyle("Label"); + rightStyle.alignment = TextAnchor.UpperRight; + + //size + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Size ", EditorStyles.boldLabel, GUILayout.Width(50)); + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Width", rightStyle, GUILayout.Width(50)); + local_size[0] = EditorGUILayout.DelayedFloatField(local_size[0]); + EditorGUILayout.LabelField("Length", rightStyle, GUILayout.Width(50)); + local_size[1] = EditorGUILayout.DelayedFloatField(local_size[1]); + EditorGUILayout.LabelField("Depth", rightStyle, GUILayout.Width(50)); + local_size[2] = EditorGUILayout.DelayedFloatField(local_size[2]); + EditorGUILayout.EndHorizontal(); + + //localCRS + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Local CRS ", EditorStyles.boldLabel); + EditorGUILayout.EndHorizontal(); + //position + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Position ", GUILayout.Width(60)); + EditorGUILayout.LabelField("X", rightStyle, GUILayout.Width(15)); + local_pos[0] = EditorGUILayout.DelayedFloatField(local_pos[0]); + EditorGUILayout.LabelField("Y", rightStyle, GUILayout.Width(15)); + local_pos[1] = EditorGUILayout.DelayedFloatField(local_pos[1]); + EditorGUILayout.LabelField("Z", rightStyle, GUILayout.Width(15)); + local_pos[2] = EditorGUILayout.DelayedFloatField(local_pos[2]); + EditorGUILayout.EndHorizontal(); + //rotation + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Rotation ", GUILayout.Width(60)); + EditorGUILayout.LabelField("X", rightStyle, GUILayout.Width(15)); + local_rot[0] = EditorGUILayout.DelayedFloatField(local_rot[0]); + EditorGUILayout.LabelField("Y", rightStyle, GUILayout.Width(15)); + local_rot[1] = EditorGUILayout.DelayedFloatField(local_rot[1]); + EditorGUILayout.LabelField("Z", rightStyle, GUILayout.Width(15)); + local_rot[2] = EditorGUILayout.DelayedFloatField(local_rot[2]); + EditorGUILayout.EndHorizontal(); + + //keyvaluetags=================================================================================================TOBEMODIFIED + /*DrawUILine(Color.gray, 1, 1); + EditorGUILayout.BeginHorizontal(); + GUILayout.Label("Tags ", EditorStyles.boldLabel); + EditorGUILayout.EndHorizontal(); + + EditorGUILayout.BeginVertical(); + Dictionary> tempPairs = worldAnchor.KeyvalueTags; + EditorGUILayout.BeginHorizontal(); + m_newKey = GUILayout.TextField(m_newKey, GUILayout.Width(300)); + if (GUILayout.Button("Add Key")) + { + if (m_newKey != "") + { + List emptyList = new List(); + worldAnchor.KeyvalueTags.Add(m_newKey, emptyList); + m_newKey = ""; + } + } + GUILayout.FlexibleSpace(); + EditorGUILayout.EndHorizontal(); + //iterator on m_newValues + int j = 0; + foreach (KeyValuePair> entry in tempPairs) + { + EditorGUILayout.BeginHorizontal(); + GUILayout.Label(entry.Key); + GUILayout.FlexibleSpace(); + if (GUILayout.Button("x", GUILayout.Width(18), GUILayout.Height(18))) + { + worldAnchor.KeyvalueTags.Remove(entry.Key); + m_newValues[j] = ""; + } + EditorGUILayout.EndHorizontal(); + + + EditorGUILayout.BeginHorizontal(); + List tempValues = entry.Value; + foreach (string value in tempValues) + { + GUILayout.Label(value); + + if (GUILayout.Button("x", GUILayout.Width(18), GUILayout.Height(18))) + { + tempValues.Remove(value); + worldAnchor.KeyvalueTags[entry.Key] = tempValues; + } + } + GUILayout.FlexibleSpace(); + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + if (m_newValues.Count < j + 1) + { + string value = ""; + m_newValues.Add(value); + } + m_newValues[j] = GUILayout.TextField(m_newValues[j], GUILayout.Width(200)); + if (GUILayout.Button("Add Value")) + { + if (m_newValues[j] != "") + { + List valueList = entry.Value; + valueList.Add(m_newValues[j]); + worldAnchor.KeyvalueTags[entry.Key] = valueList; + m_newValues[j] = ""; + } + } + GUILayout.FlexibleSpace(); + EditorGUILayout.EndHorizontal(); + + j++; + } + EditorGUILayout.EndVertical();*/ + //keyvaluetags=================================================================================================TOBEMODIFIED + + + //Actions when the ui fields have been changed + if (EditorGUI.EndChangeCheck()) + { + // + Matrix4x4 localCRS = Matrix4x4.TRS(local_pos, Quaternion.Euler(local_rot), Vector3.one); + List localCRSasFloat = new List + { + localCRS.m00, localCRS.m01, localCRS.m02, localCRS.m03, + localCRS.m10, localCRS.m11, localCRS.m12, localCRS.m13, + localCRS.m20, localCRS.m21, localCRS.m22, localCRS.m23, + localCRS.m30, localCRS.m31, localCRS.m32, localCRS.m33, + }; + worldAnchor.LocalCRS = localCRSasFloat; + + List localSizeAsFloat = new List + { + local_size.x, local_size.y, local_size.z + }; + worldAnchor.WorldAnchorSize = localSizeAsFloat; + + if (SaveInfo.instance.nodePositions.ContainsKey(worldAnchor.UUID.ToString()) && (!SaveInfo.instance.elemsToUpdate.Contains(worldAnchor.UUID.ToString()))) + { + SaveInfo.instance.elemsToUpdate.Add(worldAnchor.UUID.ToString()); + } + worldAnchorNode.MarkUnsaved(); + } + + // + //FOOTER + // + GUILayout.FlexibleSpace(); + EditorGUILayout.BeginHorizontal(); + GUILayout.FlexibleSpace(); + + var originalColor = GUI.backgroundColor; + + + //reload button + GUI.backgroundColor = Color.yellow; + if (GUILayout.Button("Reload")) + { + //lose focus of fields otherwise the selected field won't updaate + EditorGUI.FocusTextInControl(null); + if (SaveInfo.instance.nodePositions.ContainsKey(worldAnchor.UUID.ToString())) + { + if (SaveInfo.instance.elemsToUpdate.Contains(worldAnchor.UUID.ToString()) && EditorUtility.DisplayDialog("Reset elements", "Are you sure you want to lose all your changes ?", "Yes", "No")) + { + worldAnchor = WorldAnchorRequest.GetWorldAnchor(SaveInfo.instance.worldStorageServer, worldAnchor.UUID.ToString()); + worldAnchorNode.worldAnchor = worldAnchor; + ShowWindow(worldAnchorNode); + } + } + else + { + if (EditorUtility.DisplayDialog("Reset elements", "Are you sure you want to lose all your changes ?", "Yes", "No")) + { + //generate the worldAnchor attributes + List localCRS = new List(); + for (int i = 0; i < 15; i++) + { + localCRS.Add(0); + } + localCRS.Add(1); + + List worldAnchorSize = new List(); + for (int i = 0; i < 3; i++) + { + worldAnchorSize.Add(0); + } + worldAnchor = new WorldAnchor(Guid.NewGuid(), "DefaultWorldAnchor", Guid.Parse(SaveInfo.instance.worldStorageUser.UUID), localCRS, UnitSystem.CM, worldAnchorSize, new Dictionary>()); + worldAnchorNode.worldAnchor = worldAnchor; + ShowWindow(worldAnchorNode); + } + } + } + + //save button + GUI.backgroundColor = Color.green; + if (GUILayout.Button("Save")) + { + if (SaveInfo.instance.nodePositions.ContainsKey(worldAnchor.UUID.ToString())) + { + if (SaveInfo.instance.elemsToUpdate.Contains(worldAnchor.UUID.ToString())) + { + WorldAnchorRequest.UpdateWorldAnchor(SaveInfo.instance.worldStorageServer, worldAnchor); + SaveInfo.instance.elemsToUpdate.Remove(worldAnchor.UUID.ToString()); + } + } + else + { + var posX = new List(); + posX.Add(worldAnchorNode.GetPosition().x.ToString()); + var posY = new List(); + posY.Add(worldAnchorNode.GetPosition().y.ToString()); + WorldAnchor worldAnchor = worldAnchorNode.worldAnchor; + worldAnchor.KeyvalueTags["unityAuthoringPosX"] = posX; + worldAnchor.KeyvalueTags["unityAuthoringPosY"] = posY; + + String uuid = WorldAnchorRequest.AddWorldAnchor(SaveInfo.instance.worldStorageServer, worldAnchor); + + //change the uuid in its edges, if there is a new edge to be added in the world storage it needs to have the correct uuid + uuid = uuid.Replace("\"", ""); + foreach (ARFEdgeLink edge in worldAnchorNode.portIn.connections) + { + edge.worldLink.UUIDTo = Guid.Parse(uuid); + } + foreach (ARFEdgeLink edge in worldAnchorNode.portOut.connections) + { + edge.worldLink.UUIDFrom = Guid.Parse(uuid); + } + worldAnchorNode.worldAnchor.UUID = Guid.Parse(uuid); + worldAnchorNode.GUID = uuid; + worldAnchorNode.title = worldAnchor.Name; + + //Add the newly saved World Anchor to the SaveInfo singleton + Rect trackPos = new(worldAnchorNode.GetPosition().x, worldAnchorNode.GetPosition().y, 135, 77); + SaveInfo.instance.nodePositions[uuid] = trackPos; + } + worldAnchorNode.MarkSaved(); + } + GUILayout.Space(10); + EditorGUILayout.EndHorizontal(); + GUILayout.Space(10); + + GUI.backgroundColor = originalColor; + + + } + } + + private void BuildTrackableUI() + { + if (trackable != null) + { + // + //HEADER + // + + //trackable icon + EditorGUILayout.BeginHorizontal(); + Texture trackImage = (Texture)AssetDatabase.LoadAssetAtPath("Assets/ETSI.ARF/ARF World Storage API/Images/trackable.png", typeof(Texture)); + GUI.backgroundColor = Color.clear; + GUILayout.Box(trackImage, GUILayout.Width(40), GUILayout.Height(40)); + + //trackable label + EditorGUILayout.BeginVertical(GUILayout.Height(50)); + GUILayout.FlexibleSpace(); + EditorGUILayout.LabelField("TRACKABLE", EditorStyles.boldLabel); + GUILayout.FlexibleSpace(); + EditorGUILayout.EndVertical(); + EditorGUILayout.EndHorizontal(); + + //separator line + var rect = EditorGUILayout.BeginHorizontal(GUILayout.Height(10)); + DrawUILine(new Color(1, 0.31f, 0.31f, 0.9f), 5, 0); + EditorGUILayout.EndHorizontal(); + + if (trackableNode.titleContainer.Contains(trackableNode.savedIcon)) + { + //the icon to add if the node does not correspond to an element in the server + Texture2D warningImage = (Texture2D)AssetDatabase.LoadAssetAtPath("Assets/ETSI.ARF/ARF World Storage API/Images/warning.png", typeof(Texture2D)); + + GUI.backgroundColor = Color.clear; + GUILayout.BeginHorizontal(); + GUILayout.Box(warningImage, GUILayout.Width(27), GUILayout.Height(27)); + EditorGUILayout.LabelField("This element is not synchronized with the World Storage"); + GUILayout.EndHorizontal(); + } + + // + //ELEMENT PARAMETERS + // + + EditorGUI.BeginChangeCheck(); + + //uuid + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("UUID ", EditorStyles.boldLabel, GUILayout.Width(50)); + if (!SaveInfo.instance.nodePositions.ContainsKey(trackable.UUID.ToString())) + { + EditorGUILayout.LabelField("none yet (element not yet saved in the server)"); + } + else + { + EditorGUILayout.SelectableLabel(trackable.UUID.ToString(), EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight)); + } + EditorGUILayout.EndHorizontal(); + + //name + EditorGUILayout.BeginHorizontal(); + EditorGUI.BeginChangeCheck(); + EditorGUILayout.LabelField("Name ", EditorStyles.boldLabel, GUILayout.Width(50)); + trackable.Name = EditorGUILayout.DelayedTextField(trackable.Name); + if (EditorGUI.EndChangeCheck()) + { + trackableNode.title = trackable.Name; + } + EditorGUILayout.EndHorizontal(); + + //trackable's type + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Type ", EditorStyles.boldLabel, GUILayout.Width(50)); + trackable.TrackableType = (Trackable.TrackableTypeEnum)EditorGUILayout.EnumPopup(trackable.TrackableType); + EditorGUILayout.EndHorizontal(); + + //unit system + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Unit ", EditorStyles.boldLabel, GUILayout.Width(50)); + trackable.Unit = (UnitSystem)EditorGUILayout.EnumPopup(trackable.Unit); + EditorGUILayout.EndHorizontal(); + + //style for sublabels (right aligned) + var rightStyle = GUI.skin.GetStyle("Label"); + rightStyle.alignment = TextAnchor.UpperRight; + + //size + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Size ", EditorStyles.boldLabel, GUILayout.Width(50)); + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Width", rightStyle, GUILayout.Width(50)); + local_size[0] = EditorGUILayout.DelayedFloatField(local_size[0]); + EditorGUILayout.LabelField("Length", rightStyle, GUILayout.Width(50)); + local_size[1] = EditorGUILayout.DelayedFloatField(local_size[1]); + EditorGUILayout.LabelField("Depth", rightStyle, GUILayout.Width(50)); + local_size[2] = EditorGUILayout.DelayedFloatField(local_size[2]); + EditorGUILayout.EndHorizontal(); + + //localCRS + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Local CRS ", EditorStyles.boldLabel); + EditorGUILayout.EndHorizontal(); + //position + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Position ", GUILayout.Width(60)); + EditorGUILayout.LabelField("X", rightStyle, GUILayout.Width(15)); + local_pos[0] = EditorGUILayout.DelayedFloatField(local_pos[0]); + EditorGUILayout.LabelField("Y", rightStyle, GUILayout.Width(15)); + local_pos[1] = EditorGUILayout.DelayedFloatField(local_pos[1]); + EditorGUILayout.LabelField("Z", rightStyle, GUILayout.Width(15)); + local_pos[2] = EditorGUILayout.DelayedFloatField(local_pos[2]); + EditorGUILayout.EndHorizontal(); + //rotation + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Rotation ", GUILayout.Width(60)); + EditorGUILayout.LabelField("X", rightStyle, GUILayout.Width(15)); + local_rot[0] = EditorGUILayout.DelayedFloatField(local_rot[0]); + EditorGUILayout.LabelField("Y", rightStyle, GUILayout.Width(15)); + local_rot[1] = EditorGUILayout.DelayedFloatField(local_rot[1]); + EditorGUILayout.LabelField("Z", rightStyle, GUILayout.Width(15)); + local_rot[2] = EditorGUILayout.DelayedFloatField(local_rot[2]); + EditorGUILayout.EndHorizontal(); + + //encodingInofrmation + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Trackable Information ", EditorStyles.boldLabel); + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Format ", GUILayout.Width(50)); + trackable.TrackableEncodingInformation.DataFormat = (EncodingInformationStructure.DataFormatEnum)EditorGUILayout.EnumPopup(trackable.TrackableEncodingInformation.DataFormat); + EditorGUILayout.LabelField("Version ", GUILayout.Width(50)); + float floatVersion; + if (trackable.TrackableEncodingInformation._Version != null) + { + floatVersion = EditorGUILayout.DelayedFloatField(float.Parse(trackable.TrackableEncodingInformation._Version.Replace(".",","))); + } + else + { + floatVersion = EditorGUILayout.DelayedFloatField(0); + } + trackable.TrackableEncodingInformation._Version = floatVersion.ToString(); + EditorGUILayout.EndHorizontal(); + + /*//trackable payload + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Trackable Payload ", EditorStyles.boldLabel, GUILayout.Width(140)); + EditorGUILayout.LabelField("==============================================================================="); + EditorGUILayout.EndHorizontal();*/ + + //keyvaluetags=================================================================================================TOBEMODIFIED + /*EditorGUILayout.BeginHorizontal(); + GUILayout.Label("Tags ", EditorStyles.boldLabel); + EditorGUILayout.EndHorizontal(); + + EditorGUILayout.BeginVertical(); + Dictionary> tempPairs = trackable.KeyvalueTags; + EditorGUILayout.BeginHorizontal(); + m_newKey = GUILayout.TextField(m_newKey, GUILayout.Width(300)); + if (GUILayout.Button("Add Key")) + { + if (m_newKey != "") + { + List emptyList = new List(); + trackable.KeyvalueTags.Add(m_newKey, emptyList); + m_newKey = ""; + } + } + GUILayout.FlexibleSpace(); + EditorGUILayout.EndHorizontal(); + //iterator on m_newValues + int j = 0; + foreach (KeyValuePair> entry in tempPairs) + { + DrawUILine(Color.gray, 1, 1); + EditorGUILayout.BeginHorizontal(); + GUILayout.Label(entry.Key); + GUILayout.FlexibleSpace(); + if (GUILayout.Button("x", GUILayout.Width(18), GUILayout.Height(18))) + { + trackable.KeyvalueTags.Remove(entry.Key); + m_newValues[j] = ""; + } + EditorGUILayout.EndHorizontal(); + + + EditorGUILayout.BeginHorizontal(); + List tempValues = entry.Value; + foreach (string value in tempValues) + { + GUILayout.Label(value); + + if (GUILayout.Button("x", GUILayout.Width(18), GUILayout.Height(18))) + { + tempValues.Remove(value); + trackable.KeyvalueTags[entry.Key] = tempValues; + } + } + GUILayout.FlexibleSpace(); + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + if (m_newValues.Count < j + 1) + { + string value = ""; + m_newValues.Add(value); + } + m_newValues[j] = GUILayout.TextField(m_newValues[j], GUILayout.Width(200)); + if (GUILayout.Button("Add Value")) + { + if (m_newValues[j] != "") + { + List valueList = entry.Value; + valueList.Add(m_newValues[j]); + trackable.KeyvalueTags[entry.Key] = valueList; + m_newValues[j] = ""; + } + } + GUILayout.FlexibleSpace(); + EditorGUILayout.EndHorizontal(); + + j++; + } + EditorGUILayout.EndVertical();*//*EditorGUILayout.BeginHorizontal(); + GUILayout.Label("Tags ", EditorStyles.boldLabel); + EditorGUILayout.EndHorizontal(); + + EditorGUILayout.BeginVertical(); + Dictionary> tempPairs = trackable.KeyvalueTags; + EditorGUILayout.BeginHorizontal(); + m_newKey = GUILayout.TextField(m_newKey, GUILayout.Width(300)); + if (GUILayout.Button("Add Key")) + { + if (m_newKey != "") + { + List emptyList = new List(); + trackable.KeyvalueTags.Add(m_newKey, emptyList); + m_newKey = ""; + } + } + GUILayout.FlexibleSpace(); + EditorGUILayout.EndHorizontal(); + //iterator on m_newValues + int j = 0; + foreach (KeyValuePair> entry in tempPairs) + { + DrawUILine(Color.gray, 1, 1); + EditorGUILayout.BeginHorizontal(); + GUILayout.Label(entry.Key); + GUILayout.FlexibleSpace(); + if (GUILayout.Button("x", GUILayout.Width(18), GUILayout.Height(18))) + { + trackable.KeyvalueTags.Remove(entry.Key); + m_newValues[j] = ""; + } + EditorGUILayout.EndHorizontal(); + + + EditorGUILayout.BeginHorizontal(); + List tempValues = entry.Value; + foreach (string value in tempValues) + { + GUILayout.Label(value); + + if (GUILayout.Button("x", GUILayout.Width(18), GUILayout.Height(18))) + { + tempValues.Remove(value); + trackable.KeyvalueTags[entry.Key] = tempValues; + } + } + GUILayout.FlexibleSpace(); + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + if (m_newValues.Count < j + 1) + { + string value = ""; + m_newValues.Add(value); + } + m_newValues[j] = GUILayout.TextField(m_newValues[j], GUILayout.Width(200)); + if (GUILayout.Button("Add Value")) + { + if (m_newValues[j] != "") + { + List valueList = entry.Value; + valueList.Add(m_newValues[j]); + trackable.KeyvalueTags[entry.Key] = valueList; + m_newValues[j] = ""; + } + } + GUILayout.FlexibleSpace(); + EditorGUILayout.EndHorizontal(); + + j++; + } + EditorGUILayout.EndVertical();*/ + //keyvaluetags=================================================================================================TOBEMODIFIED + + + //Actions when the ui fields have been changed + if (EditorGUI.EndChangeCheck()) + { + // + Matrix4x4 localCRS = Matrix4x4.TRS(local_pos, Quaternion.Euler(local_rot), Vector3.one); + List localCRSasFloat = new List + { + localCRS.m00, localCRS.m01, localCRS.m02, localCRS.m03, + localCRS.m10, localCRS.m11, localCRS.m12, localCRS.m13, + localCRS.m20, localCRS.m21, localCRS.m22, localCRS.m23, + localCRS.m30, localCRS.m31, localCRS.m32, localCRS.m33, + }; + trackable.LocalCRS = localCRSasFloat; + + List localSizeAsFloat = new List + { + local_size.x, local_size.y, local_size.z + }; + trackable.TrackableSize = localSizeAsFloat; + + if (SaveInfo.instance.nodePositions.ContainsKey(trackable.UUID.ToString()) && (!SaveInfo.instance.elemsToUpdate.Contains(trackable.UUID.ToString()))) + { + SaveInfo.instance.elemsToUpdate.Add(trackable.UUID.ToString()); + } + trackableNode.MarkUnsaved(); + } + + // + //FOOTER + // + GUILayout.FlexibleSpace(); + EditorGUILayout.BeginHorizontal(); + GUILayout.FlexibleSpace(); + + var originalColor = GUI.backgroundColor; + + //reload button + GUI.backgroundColor = Color.yellow; + if (GUILayout.Button("Reload")) + { + //lose focus of fields otherwise the selected field won't updaate + EditorGUI.FocusTextInControl(null); + if (SaveInfo.instance.nodePositions.ContainsKey(trackable.UUID.ToString())) + { + if (SaveInfo.instance.elemsToUpdate.Contains(trackable.UUID.ToString()) && EditorUtility.DisplayDialog("Reset elements", "Are you sure you want to lose all your changes ?", "Yes", "No")) + { + trackable = TrackableRequest.GetTrackable(SaveInfo.instance.worldStorageServer, trackable.UUID.ToString()); + trackableNode.trackable = trackable; + ShowWindow(trackableNode); + } + } + else + { + if (EditorUtility.DisplayDialog("Reset elements", "Are you sure you want to lose all your changes ?", "Yes", "No")) + { + //generate the Trackables's attributes + EncodingInformationStructure trackableEncodingInformation = new EncodingInformationStructure(EncodingInformationStructure.DataFormatEnum.OTHER, "0"); + + List localCRS = new(); + for (int i = 0; i < 15; i++) + { + localCRS.Add(0); + } + localCRS.Add(1); + + List trackableSize = new(); + for (int i = 0; i < 3; i++) + { + trackableSize.Add(0); + } + + Trackable trackable = new Trackable(Guid.NewGuid(), "Defaulttrackable", Guid.Parse(SaveInfo.instance.worldStorageUser.UUID), Trackable.TrackableTypeEnum.OTHER, trackableEncodingInformation, new byte[64], localCRS, UnitSystem.CM, trackableSize, new Dictionary>()); + trackableNode.trackable = trackable; + ShowWindow(trackableNode); + } + } + } + + //save button + GUI.backgroundColor = Color.green; + if (GUILayout.Button("Save")) + { + if (SaveInfo.instance.nodePositions.ContainsKey(trackable.UUID.ToString())) + { + if (SaveInfo.instance.elemsToUpdate.Contains(trackable.UUID.ToString())) + { + TrackableRequest.UpdateTrackable(SaveInfo.instance.worldStorageServer, trackable); + SaveInfo.instance.elemsToUpdate.Remove(trackable.UUID.ToString()); + } + } + else + { + var posX = new List(); + posX.Add(trackableNode.GetPosition().x.ToString()); + var posY = new List(); + posY.Add(trackableNode.GetPosition().y.ToString()); + Trackable trackable = trackableNode.trackable; + trackable.KeyvalueTags["unityAuthoringPosX"] = posX; + trackable.KeyvalueTags["unityAuthoringPosY"] = posY; + String uuid = TrackableRequest.AddTrackable(SaveInfo.instance.worldStorageServer, trackable); + + //change the uuid in its edges, if there is a new edge to be added in the world storage it needs to have the correct uuid + uuid = uuid.Replace("\"", ""); + foreach (ARFEdgeLink edge in trackableNode.portIn.connections) + { + edge.worldLink.UUIDTo = Guid.Parse(uuid); + } + foreach (ARFEdgeLink edge in trackableNode.portOut.connections) + { + edge.worldLink.UUIDFrom = Guid.Parse(uuid); + } + trackableNode.trackable.UUID = Guid.Parse(uuid); + trackableNode.GUID = uuid; + trackableNode.title = trackable.Name; + + //Add the newly saved Trackable to the SaveInfo singleton + Rect trackPos = new(trackableNode.GetPosition().x, trackableNode.GetPosition().y, 135, 77); + SaveInfo.instance.nodePositions[uuid] = trackPos; + } + trackableNode.MarkSaved(); + } + GUILayout.Space(10); + EditorGUILayout.EndHorizontal(); + GUILayout.Space(10); + + GUI.backgroundColor = originalColor; + + + } + } + + private void BuildWorldLinkUI() + { + if (worldLink != null) + { + // + //HEADER + // + + //world link icon + EditorGUILayout.BeginHorizontal(); + Texture linkImage = (Texture)AssetDatabase.LoadAssetAtPath("Assets/ETSI.ARF/ARF World Storage API/Images/link.png", typeof(Texture)); + GUI.backgroundColor = Color.clear; + GUILayout.Box(linkImage, GUILayout.Width(40), GUILayout.Height(40)); + + //world link label + EditorGUILayout.BeginVertical(GUILayout.Height(50)); + GUILayout.FlexibleSpace(); + EditorGUILayout.LabelField("WORLD LINK", EditorStyles.boldLabel); + GUILayout.FlexibleSpace(); + EditorGUILayout.EndVertical(); + EditorGUILayout.EndHorizontal(); + + //separator line + var rect = EditorGUILayout.BeginHorizontal(GUILayout.Height(10)); + DrawUILine(new Color(0.66f, 0.39f, 1, 0.77f), 5, 5); + EditorGUILayout.EndHorizontal(); + + if (worldLinkEdge.contentContainer.Contains(worldLinkEdge.savedIcon)) + { + //the icon to add if the node does not correspond to an element in the server + Texture2D warningImage = (Texture2D)AssetDatabase.LoadAssetAtPath("Assets/ETSI.ARF/ARF World Storage API/Images/warning.png", typeof(Texture2D)); + + GUI.backgroundColor = Color.clear; + GUILayout.BeginHorizontal(); + GUILayout.Box(warningImage, GUILayout.Width(27), GUILayout.Height(27)); + EditorGUILayout.LabelField("This element is not synchronized with the World Storage"); + GUILayout.EndHorizontal(); + } + + //ELEMENT'S ATTRIBUTES + EditorGUI.BeginChangeCheck(); + + //uuid + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("UUID ", EditorStyles.boldLabel, GUILayout.Width(50)); + if (!SaveInfo.instance.linkIds.Contains(worldLink.UUID.ToString())) + { + EditorGUILayout.LabelField("none yet (element not yet saved in the server)"); + } + else + { + EditorGUILayout.SelectableLabel(worldLink.UUID.ToString(), EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight)); + } + EditorGUILayout.EndHorizontal(); + + //source element + EditorGUILayout.LabelField("Source Element (From element)", EditorStyles.boldLabel); + EditorGUILayout.BeginHorizontal(); + GUILayout.Space(50); + EditorGUILayout.LabelField("Name ", GUILayout.Width(75)); + EditorGUILayout.LabelField(worldLinkEdge.output.node.title); + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + GUILayout.Space(50); + EditorGUILayout.LabelField("Type ", GUILayout.Width(75)); + EditorGUILayout.LabelField(worldLink.TypeFrom.ToString(), GUILayout.Width(80)); + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + GUILayout.Space(50); + EditorGUILayout.LabelField("UUID ", GUILayout.Width(75)); + if (SaveInfo.instance.nodePositions.ContainsKey(worldLink.UUIDFrom.ToString())) + { + EditorGUILayout.LabelField(worldLink.UUIDFrom.ToString()); + } + else + { + EditorGUILayout.LabelField("no UUID yet (element not yet saved in the server)"); + } + EditorGUILayout.EndHorizontal(); + + //target element + EditorGUILayout.LabelField("Target Element (To element)", EditorStyles.boldLabel); + EditorGUILayout.BeginHorizontal(); + GUILayout.Space(50); + EditorGUILayout.LabelField("Name ", GUILayout.Width(70)); + EditorGUILayout.LabelField(worldLinkEdge.input.node.title); + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + GUILayout.Space(50); + EditorGUILayout.LabelField("Type ", GUILayout.Width(70)); + EditorGUILayout.LabelField(worldLink.TypeTo.ToString(), GUILayout.Width(80)); + EditorGUILayout.EndHorizontal(); + EditorGUILayout.BeginHorizontal(); + GUILayout.Space(50); + EditorGUILayout.LabelField("UUID ", GUILayout.Width(70)); + if (SaveInfo.instance.nodePositions.ContainsKey(worldLink.UUIDTo.ToString())) + { + EditorGUILayout.LabelField(worldLink.UUIDTo.ToString()); + } + else + { + EditorGUILayout.LabelField("no UUID yet (element not yet saved in the server)"); + } + EditorGUILayout.EndHorizontal(); + + //unit system + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Unit ", EditorStyles.boldLabel, GUILayout.Width(50)); + worldLink.Unit = (UnitSystem)EditorGUILayout.EnumPopup(worldLink.Unit); + EditorGUILayout.EndHorizontal(); + + //style for sublabels (right aligned) + var rightStyle = GUI.skin.GetStyle("Label"); + rightStyle.alignment = TextAnchor.UpperRight; + + //localCRS + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("3D Transform ", EditorStyles.boldLabel); + EditorGUILayout.EndHorizontal(); + //position + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Position ", GUILayout.Width(60)); + EditorGUILayout.LabelField("X", rightStyle, GUILayout.Width(15)); + local_pos[0] = EditorGUILayout.DelayedFloatField(local_pos[0]); + EditorGUILayout.LabelField("Y", rightStyle, GUILayout.Width(15)); + local_pos[1] = EditorGUILayout.DelayedFloatField(local_pos[1]); + EditorGUILayout.LabelField("Z", rightStyle, GUILayout.Width(15)); + local_pos[2] = EditorGUILayout.DelayedFloatField(local_pos[2]); + EditorGUILayout.EndHorizontal(); + //rotation + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("Rotation ", GUILayout.Width(60)); + EditorGUILayout.LabelField("X", rightStyle, GUILayout.Width(15)); + local_rot[0] = EditorGUILayout.DelayedFloatField(local_rot[0]); + EditorGUILayout.LabelField("Y", rightStyle, GUILayout.Width(15)); + local_rot[1] = EditorGUILayout.DelayedFloatField(local_rot[1]); + EditorGUILayout.LabelField("Z", rightStyle, GUILayout.Width(15)); + local_rot[2] = EditorGUILayout.DelayedFloatField(local_rot[2]); + EditorGUILayout.EndHorizontal(); + + //Actions when the ui fields have been changed + if (EditorGUI.EndChangeCheck()) + { + // + Matrix4x4 localCRS = Matrix4x4.TRS(local_pos, Quaternion.Euler(local_rot), Vector3.one); + List localCRSasFloat = new List + { + localCRS.m00, localCRS.m01, localCRS.m02, localCRS.m03, + localCRS.m10, localCRS.m11, localCRS.m12, localCRS.m13, + localCRS.m20, localCRS.m21, localCRS.m22, localCRS.m23, + localCRS.m30, localCRS.m31, localCRS.m32, localCRS.m33, + }; + worldLink.Transform = localCRSasFloat; + + if (SaveInfo.instance.linkIds.Contains(worldLink.UUID.ToString()) && (!SaveInfo.instance.elemsToUpdate.Contains(worldLink.UUID.ToString()))) + { + SaveInfo.instance.elemsToUpdate.Add(worldLink.UUID.ToString()); + } + worldLinkEdge.MarkUnsaved(); + } + + // + //FOOTER + // + GUILayout.FlexibleSpace(); + EditorGUILayout.BeginHorizontal(); + GUILayout.FlexibleSpace(); + + var originalColor = GUI.backgroundColor; + + //reload button + GUI.backgroundColor = Color.yellow; + if (GUILayout.Button("Reload")) + { + //lose focus of fields otherwise the selected field won't updaate + EditorGUI.FocusTextInControl(null); + if (SaveInfo.instance.linkIds.Contains(worldLink.UUID.ToString())) + { + if (SaveInfo.instance.elemsToUpdate.Contains(worldLink.UUID.ToString()) && EditorUtility.DisplayDialog("Reset elements", "Are you sure you want to lose all your changes ?", "Yes", "No")) + { + worldLink = WorldLinkRequest.GetWorldLink(SaveInfo.instance.worldStorageServer, worldLink.UUID.ToString()); + worldLinkEdge.worldLink = worldLink; + ShowWindow(worldLinkEdge); + } + } + else + { + if (EditorUtility.DisplayDialog("Reset elements", "Are you sure you want to lose all your changes ?", "Yes", "No")) + { + + List transform = new List(); + for (int i = 0; i < 15; i++) + { + transform.Add(0); + } + transform.Add(1); + + worldLink.Transform = transform; + worldLink.Unit = UnitSystem.CM; + ShowWindow(worldLinkEdge); + } + } + } + + //save button + GUI.backgroundColor = Color.green; + if (GUILayout.Button("Save")) + { + //if one of the connected elements is not in the server, you can't save the link + if ((SaveInfo.instance.nodePositions.ContainsKey(worldLink.UUIDTo.ToString()) && SaveInfo.instance.nodePositions.ContainsKey(worldLink.UUIDFrom.ToString()))) + { + if (SaveInfo.instance.linkIds.Contains(worldLink.UUID.ToString())) + { + if (SaveInfo.instance.elemsToUpdate.Contains(worldLink.UUID.ToString())) + { + WorldLinkRequest.UpdateWorldLink(SaveInfo.instance.worldStorageServer, worldLink); + SaveInfo.instance.elemsToUpdate.Remove(worldLink.UUID.ToString()); + } + } + else + { + String uuid = WorldLinkRequest.AddWorldLink(SaveInfo.instance.worldStorageServer, worldLink); + + //Add the newly saved WorldLink to the SaveInfo singleton + uuid = uuid.Replace("\"", ""); + worldLink.UUID = Guid.Parse(uuid); + worldLinkEdge.GUID = uuid; + SaveInfo.instance.linkIds.Add(uuid); + } + worldLinkEdge.MarkSaved(); + } + else + { + EditorUtility.DisplayDialog("Error", "You are not able to save this link because at least one of its connected elements is not saved in the World Storage", "Ok"); + } + } + GUILayout.Space(10); + EditorGUILayout.EndHorizontal(); + GUILayout.Space(10); + + } + } + + //utilty method to draw lines + public static void DrawUILine(Color color, int thickness = 2, int padding = 10) + { + Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(padding + thickness)); + r.height = thickness; + r.y += padding/2; + r.x-=2; + r.width +=6; + EditorGUI.DrawRect(r, color); + } + } +} \ No newline at end of file diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/GraphEditorWindow.cs.meta b/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/GraphEditorWindow.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..10797498c8160eb8e60e846ba012c764bd775c18 --- /dev/null +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/GraphEditorWindow.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e219817d65c8b1f40ad85e6185e89e92 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/TrackableWindow.cs b/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/TrackableWindow.cs index 9847de9ed6d90f421d0af096a2e55836ecdc17c1..989da6661959e6fd461ad62fe2d1e906e96d7531 100644 --- a/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/TrackableWindow.cs +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/TrackableWindow.cs @@ -27,6 +27,7 @@ using UnityEngine; using UnityEditor; using TMPro; using ETSI.ARF.WorldStorage.REST; +using System; #if USING_OPENAPI_GENERATOR using Org.OpenAPITools.Api; @@ -70,6 +71,11 @@ namespace ETSI.ARF.WorldStorage.UI private Color ori; private GUIStyle gsTest; + //graph params to generate the node + public bool useCoord; + public float nodePosX = 0; + public float nodePosY = 0; + public static void ShowWindow(WorldStorageServer ws, WorldStorageUser user, string UUID = "") { winSingleton = EditorWindow.GetWindow(typeof(TrackableWindow), false, "ETSI ARF - Trackable") as TrackableWindow; @@ -179,8 +185,12 @@ namespace ETSI.ARF.WorldStorage.UI UUID = TrackableRequest.UpdateTrackable(worldStorageServer, obj); UUID = UUID.Trim('"'); //Bugfix: remove " from server return value } - WorldStorageWindow.WorldStorageWindowSingleton.GetTrackables(); - WorldStorageWindow.WorldStorageWindowSingleton.Repaint(); + if (WorldStorageWindow.WorldStorageWindowSingleton != null) + { + WorldStorageWindow.WorldStorageWindowSingleton.GetTrackables(); + WorldStorageWindow.WorldStorageWindowSingleton.Repaint(); + } + Close(); } GUI.backgroundColor = WorldStorageWindow.arfColors[3]; @@ -193,8 +203,12 @@ namespace ETSI.ARF.WorldStorage.UI creatorUUID = System.Guid.Empty.ToString(); type = Trackable.TrackableTypeEnum.OTHER; unit = UnitSystem.CM; - WorldStorageWindow.WorldStorageWindowSingleton.GetTrackables(); - WorldStorageWindow.WorldStorageWindowSingleton.Repaint(); + if (WorldStorageWindow.WorldStorageWindowSingleton != null) + { + WorldStorageWindow.WorldStorageWindowSingleton.GetTrackables(); + WorldStorageWindow.WorldStorageWindowSingleton.Repaint(); + } + Close(); } GUI.backgroundColor = ori; @@ -319,6 +333,14 @@ namespace ETSI.ARF.WorldStorage.UI System.Guid _uuid = System.Guid.Parse(UUID); System.Guid _creator = System.Guid.Parse(worldStorageUser.UUID); Trackable t = new Trackable(_uuid, customName, _creator, type, trackableEncodingInformation, trackablePayload, _localCRS, unit, _trackableSize, keyValueTags); + + var posX = new List(); + posX.Add(nodePosX.ToString()); + t.KeyvalueTags["unityAuthoringPosX"] = posX; + var posY = new List(); + posY.Add(nodePosY.ToString()); + t.KeyvalueTags["unityAuthoringPosY"] = posY; + return t; } } diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/TrackableWindow.cs.meta b/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/TrackableWindow.cs.meta index 40f6111b39dd386428e0f54851283061c614124f..020c2af305925803868dbb5f22c964e5176c8f49 100644 --- a/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/TrackableWindow.cs.meta +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/TrackableWindow.cs.meta @@ -3,7 +3,10 @@ guid: 229d5ea484d30f945b9318581fb4f2da MonoImporter: externalObjects: {} serializedVersion: 2 - defaultReferences: [] + defaultReferences: + - m_ViewDataDictionary: {instanceID: 0} + - worldStorageServer: {fileID: 11400000, guid: 4f997253243de534dad12937f1284975, type: 2} + - worldStorageUser: {instanceID: 0} executionOrder: 0 icon: {instanceID: 0} userData: diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/WorldAnchorWindow.cs b/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/WorldAnchorWindow.cs index 8260aae91c3d07221c9b9fe4b70ed7d48e19f0b0..a54fda35f763e8c8e7bc8e2c9413fbc22d2efb07 100644 --- a/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/WorldAnchorWindow.cs +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/WorldAnchorWindow.cs @@ -27,6 +27,7 @@ using UnityEngine; using UnityEditor; using TMPro; using ETSI.ARF.WorldStorage.REST; +using System; #if USING_OPENAPI_GENERATOR using Org.OpenAPITools.Api; @@ -67,6 +68,11 @@ namespace ETSI.ARF.WorldStorage.UI private Color ori; private GUIStyle gsTest; + //graph params to generate the node + public bool useCoord; + public float nodePosX = 0; + public float nodePosY = 0; + public static void ShowWindow(WorldStorageServer ws, WorldStorageUser user, string UUID = "") { winSingleton = EditorWindow.GetWindow(typeof(WorldAnchorWindow), false, "ETSI ARF - World Anchor") as WorldAnchorWindow; @@ -178,6 +184,7 @@ namespace ETSI.ARF.WorldStorage.UI WorldStorageWindow.WorldStorageWindowSingleton.GetWorldAnchors(); WorldStorageWindow.WorldStorageWindowSingleton.Repaint(); } + Close(); } GUI.backgroundColor = WorldStorageWindow.arfColors[3]; @@ -189,8 +196,12 @@ namespace ETSI.ARF.WorldStorage.UI customName = "Warning: Object deleted !"; creatorUUID = System.Guid.Empty.ToString(); unit = UnitSystem.CM; - WorldStorageWindow.WorldStorageWindowSingleton.GetWorldAnchors(); - WorldStorageWindow.WorldStorageWindowSingleton.Repaint(); + if (WorldStorageWindow.WorldStorageWindowSingleton != null) + { + WorldStorageWindow.WorldStorageWindowSingleton.GetWorldAnchors(); + WorldStorageWindow.WorldStorageWindowSingleton.Repaint(); + } + Close(); } GUI.backgroundColor = ori; @@ -277,9 +288,9 @@ namespace ETSI.ARF.WorldStorage.UI #else List trackableDimension = new List(); #endif - _worldAnchorSize.Add(worldAnchorSize.x); _worldAnchorSize.Add(worldAnchorSize.x); _worldAnchorSize.Add(worldAnchorSize.y); + _worldAnchorSize.Add(worldAnchorSize.z); Debug.Log("Created dimension"); Matrix4x4 localCRS = new Matrix4x4(); @@ -299,6 +310,14 @@ namespace ETSI.ARF.WorldStorage.UI System.Guid _uuid = System.Guid.Parse(UUID); System.Guid _creator = System.Guid.Parse(worldStorageUser.UUID); WorldAnchor t = new WorldAnchor(_uuid, customName, _creator, _localCRS, unit, _worldAnchorSize, keyValueTags); + + var posX = new List(); + posX.Add(nodePosX.ToString()); + t.KeyvalueTags["unityAuthoringPosX"] = posX; + var posY = new List(); + posY.Add(nodePosY.ToString()); + t.KeyvalueTags["unityAuthoringPosY"] = posY; + return t; } } diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/WorldGraphWindow.cs b/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/WorldGraphWindow.cs new file mode 100644 index 0000000000000000000000000000000000000000..867c75803fa0fd71b2017b2fd25458203a2170c2 --- /dev/null +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/WorldGraphWindow.cs @@ -0,0 +1,289 @@ +// +// ARF - Augmented Reality Framework (ETSI ISG ARF) +// +// Copyright 2022 ETSI +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Last change: July 2022 +// + +using Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Graph; +using ETSI.ARF.WorldStorage; +using ETSI.ARF.WorldStorage.REST; +using ETSI.ARF.WorldStorage.UI; +using Org.OpenAPITools.Model; +using System; +using System.Collections.Generic; +using UnityEditor; +using UnityEditor.Experimental.GraphView; +using UnityEditor.UIElements; +using UnityEngine; +using UnityEngine.UIElements; + +namespace Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Windows +{ + public class WorldGraphWindow : EditorWindow + { + + [HideInInspector] public WorldStorageServer worldStorageServer; + [HideInInspector] public WorldStorageUser worldStorageUser; + + private ARFGraphView myGraph; + + //to delay the reframe (otherwise it reframes when the graph isn't built yet) + int twoFrames = 0; + + public static void ShowWindowFromWorldStorageWindow(WorldStorageServer server, WorldStorageUser user) + { + var window = GetWindow("Graph Editor", true, typeof(SceneView)); + if (window.myGraph != null) + { + if (window.myGraph.ServerAndLocalDifferent() && EditorUtility.DisplayDialog("Saving node positions", "The World Graph has been modified. \nWould you like to push the modifications to the server ?", "Yes", "No")) + { + window.myGraph.SaveInServer(); + } + window.rootVisualElement.Remove(window.myGraph); + } + GraphEditorWindow.ResetWindow(); + window.worldStorageServer = server; + window.worldStorageUser = user; + SaveInfo.instance.nodePositions = null; + window.OnEnable(); + } + + [MenuItem("ARFWorldStorage/Edit Graph...")] + public static void ShowWindow() + { + GetWindow("Graph Editor", true, typeof(SceneView)); + } + + public void OnEnable() + { + if (worldStorageServer != null) + { + try { + if (SaveInfo.instance.nodePositions == null) + { + SaveInfo.instance.InitNodePos(worldStorageServer, worldStorageUser); + } + ConstructGraphView(); + myGraph.style.top = Length.Percent(11); + myGraph.style.bottom = Length.Percent(5); + rootVisualElement.Add(myGraph); + } + catch (Exception e) + { + EditorUtility.DisplayDialog("Error", "The server you selected is unreachable", "Ok"); + myGraph = null; + Debug.Log(e.ToString()); + } + } + } + + //initiate the graphView Attribute + public void ConstructGraphView() + { + myGraph = new ARFGraphView + { + name = "ARF Graph", + worldStorageServer = worldStorageServer, + worldStorageUser = worldStorageUser + }; + //top offset so that the graph does'nt overlap with the rest of the ui + myGraph.style.top = Length.Percent(11); + myGraph.PaintWorldStorage(); + myGraph.StretchToParentSize(); + SaveInfo.instance.toReFrame = true; + } + + + void OnGUI() + { + if (SaveInfo.instance.nodePositions == null) + { + SaveInfo.instance.InitNodePos(worldStorageServer, worldStorageUser); + } + + + EditorGUILayout.BeginVertical(); + + EditorGUI.BeginChangeCheck(); + worldStorageServer = (WorldStorageServer)EditorGUILayout.ObjectField("World Storage Server", worldStorageServer, typeof(WorldStorageServer), false, GUILayout.Width(500)); + if (EditorGUI.EndChangeCheck()) + { + GraphEditorWindow.ResetWindow(); + + if((myGraph != null)) + { + if (myGraph.ServerAndLocalDifferent() && EditorUtility.DisplayDialog("Saving node positions", "The World Graph has been modified. \nWould you like to push the modifications to the server ?", "Yes", "No")) + { + myGraph.SaveInServer(); + } + rootVisualElement.Remove(myGraph); + } + if(worldStorageServer != null) + { + try + { + SaveInfo.instance.InitNodePos(worldStorageServer, worldStorageUser); + ConstructGraphView(); + myGraph.style.top = Length.Percent(11); + myGraph.style.bottom = Length.Percent(5); + rootVisualElement.Add(myGraph); + } + catch (Exception e) + { + EditorUtility.DisplayDialog("Error", "The server you selected is unreachable", "Ok"); + myGraph = null; + Debug.Log(e.ToString()); + } + } + else + { + myGraph = null; + } + } + + + //style for copyrights label (left aligned) + var leftStyle = GUI.skin.GetStyle("Label"); + leftStyle.alignment = TextAnchor.MiddleLeft; + + GUILayout.Label("Augmented Reality Framework", leftStyle); + GUILayout.Label("Copyright (C) 2022, ETSI (BSD 3-Clause License)", leftStyle); + + //reframe all elements to see them all + if (SaveInfo.instance.toReFrame && (twoFrames == 2)) + { + myGraph.FrameAllElements(); + SaveInfo.instance.toReFrame = false; + twoFrames = 0; + } + else if (SaveInfo.instance.toReFrame) + { + twoFrames++; + } + EditorGUILayout.EndVertical(); + + GUILayout.FlexibleSpace(); + + //Notify the user that the graph is different from the one in the server + if (myGraph != null) + { + if (myGraph.ServerAndLocalDifferent()) + { + //the icon to add if the node does not correspond to an element in the server + Texture2D warningImage = (Texture2D)AssetDatabase.LoadAssetAtPath("Assets/ETSI.ARF/ARF World Storage API/Images/warning.png", typeof(Texture2D)); + + GUI.backgroundColor = Color.clear; + GUILayout.BeginHorizontal(); + GUILayout.Box(warningImage, GUILayout.Width(27), GUILayout.Height(27)); + GUILayout.Box("There are elements in your graph that have been added, modified or deleted ! The current graph is not synchronized with the World Storage", leftStyle, GUILayout.ExpandWidth(true), GUILayout.Height(27)); + GUILayout.EndHorizontal(); + } + } + } + + public void DeleteNode(ARFNode node) + { + rootVisualElement.Remove(myGraph); + node.DisconnectAllPorts(myGraph); + myGraph.DeleteElements(new List{ node }); + rootVisualElement.Add(myGraph); + } + + public void DeleteEdge(ARFEdgeLink edge) + { + rootVisualElement.Remove(myGraph); + myGraph.DeleteElements(new List { edge }); + rootVisualElement.Add(myGraph); + } + } + + public class SaveInfo : ScriptableSingleton + { + [SerializeField] + public Dictionary nodePositions; + public List linkIds; + + public Dictionary elemsToRemove; + public List elemsToUpdate; + + //keep the info of the graph reframe + public Boolean toReFrame = false; + + public WorldStorageServer worldStorageServer; + public WorldStorageUser worldStorageUser; + + public void InitNodePos(WorldStorageServer server, WorldStorageUser user) + { + worldStorageServer = server; + worldStorageUser = user; + + instance.nodePositions = new Dictionary(); + foreach (Trackable track in TrackableRequest.GetAllTrackables(worldStorageServer)) + { + if (track.KeyvalueTags.ContainsKey("unityAuthoringPosX") && track.KeyvalueTags.ContainsKey("unityAuthoringPosY")) + { + var posX = RoundToNearestHalf(float.Parse(track.KeyvalueTags["unityAuthoringPosX"][0])); + var posY = RoundToNearestHalf(float.Parse(track.KeyvalueTags["unityAuthoringPosY"][0])); + Rect trackPos = new(posX, posY, 135, 77); + instance.nodePositions[track.UUID.ToString()] = trackPos; + } + else + { + Rect trackPos = new(0, 0, 135, 77); + instance.nodePositions[track.UUID.ToString()] = trackPos; + } + } + foreach (WorldAnchor wa in WorldAnchorRequest.GetAllWorldAnchors(worldStorageServer)) + { + if (wa.KeyvalueTags.ContainsKey("unityAuthoringPosX") && wa.KeyvalueTags.ContainsKey("unityAuthoringPosY")) + { + var posX = RoundToNearestHalf(float.Parse(wa.KeyvalueTags["unityAuthoringPosX"][0])); + var posY = RoundToNearestHalf(float.Parse(wa.KeyvalueTags["unityAuthoringPosY"][0])); + Rect waPos = new(posX, posY, 135, 77); + instance.nodePositions[wa.UUID.ToString()] = waPos; + } + else + { + Rect trackPos = new(0, 0, 135, 77); + instance.nodePositions[wa.UUID.ToString()] = trackPos; + } + } + + instance.linkIds = new List(); + foreach (WorldLink link in WorldLinkRequest.GetAllWorldLinks(worldStorageServer)) + { + instance.linkIds.Add(link.UUID.ToString()); + } + + instance.elemsToRemove = new Dictionary(); + instance.elemsToUpdate = new List(); + } + + //method to predict the position of a node (the float that will be saved in the PositionInfo singleton) + public static float RoundToNearestHalf(float a) + { + return a = Mathf.Round(a * 2f) * 0.5f; + } + + public static void PrintInfo() + { + Debug.Log("elems to delete : " + string.Join(", ", instance.elemsToRemove.Keys)); + Debug.Log("elems to update : " + string.Join(", ", instance.elemsToUpdate)); + Debug.Log("elems tout court : " + string.Join(", ", instance.nodePositions.Keys)); + } + } +} \ No newline at end of file diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/WorldGraphWindow.cs.meta b/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/WorldGraphWindow.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..add62927e11e960a03f3343413c056b51ab7b98d --- /dev/null +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/WorldGraphWindow.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 2c1a0c92306453d46897c1af6cb5c2f9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: + - m_ViewDataDictionary: {instanceID: 0} + - worldStorageServer: {instanceID: 0} + - worldStorageUser: {fileID: 11400000, guid: c0696089e4a855b46ad490437919b1e8, type: 2} + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/WorldStorageWindow.cs b/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/WorldStorageWindow.cs index 29c5e8fb0540a85b3f6c7b3f52429fbdb5c2c9a1..a41c5e58e22ab47e61367b798455eaf602eca5a9 100644 --- a/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/WorldStorageWindow.cs +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/WorldStorageWindow.cs @@ -27,7 +27,8 @@ using UnityEngine; using UnityEditor; using ETSI.ARF.WorldStorage; using ETSI.ARF.WorldStorage.REST; - +using Assets.ETSI.ARF.ARF_World_Storage_API.Editor.Windows; + #if USING_OPENAPI_GENERATOR using Org.OpenAPITools.Api; using Org.OpenAPITools.Model; @@ -130,6 +131,13 @@ namespace ETSI.ARF.WorldStorage.UI GUILayout.Label("Port: " + worldStorageServer.port); #endif + GUI.backgroundColor = WorldStorageWindow.arfColors[4]; + if (GUILayout.Button("Open World Representation Graph Window...")) + { + WorldGraphWindow.ShowWindowFromWorldStorageWindow(worldStorageServer, worldStorageUser); + } + GUI.backgroundColor = ori; + DrawElementStuffs(); EditorGUILayout.EndScrollView(); @@ -188,13 +196,6 @@ namespace ETSI.ARF.WorldStorage.UI ScriptableObject target = this; SerializedObject so = new SerializedObject(target); - //GUI.backgroundColor = WorldStorageWindow.arfColors[4]; - if (GUILayout.Button("Open World Graph Window...")) - { - //GraphWindow.ShowWindow(); - } - GUI.backgroundColor = ori; - // ########################################################### // Get creators // ########################################################### diff --git a/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/WorldStorageWindow.cs.meta b/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/WorldStorageWindow.cs.meta index c8d7fb07f3381194035bfdd86bde1d0ea9b49ac6..ec99c51dab094a4ad96d5a8815ad02617d7c3307 100644 --- a/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/WorldStorageWindow.cs.meta +++ b/Assets/ETSI.ARF/ARF World Storage API/Editor/Windows/WorldStorageWindow.cs.meta @@ -3,7 +3,10 @@ guid: a1647df9b48bf4f49a664a929fff57ff MonoImporter: externalObjects: {} serializedVersion: 2 - defaultReferences: [] + defaultReferences: + - m_ViewDataDictionary: {instanceID: 0} + - worldStorageServer: {fileID: 11400000, guid: 4f997253243de534dad12937f1284975, type: 2} + - worldStorageUser: {fileID: 11400000, guid: c0696089e4a855b46ad490437919b1e8, type: 2} executionOrder: 0 icon: {instanceID: 0} userData: diff --git a/Assets/ETSI.ARF/ARF World Storage API/Images.meta b/Assets/ETSI.ARF/ARF World Storage API/Images.meta index bb9559bf302087e412462086f6bcd17a7a5b64b4..e91faab6ea0fbedbaba1bfe5063740f6927eb413 100644 --- a/Assets/ETSI.ARF/ARF World Storage API/Images.meta +++ b/Assets/ETSI.ARF/ARF World Storage API/Images.meta @@ -1,5 +1,9 @@ fileFormatVersion: 2 +<<<<<<< HEAD +guid: 7d34ace7d2e2513479736d20d0c95ad0 +======= guid: 959ac6161f5900d4aa7903c24bc5a31d +>>>>>>> develop folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/ETSI.ARF/ARF World Storage API/Images/cloud.png b/Assets/ETSI.ARF/ARF World Storage API/Images/cloud.png new file mode 100644 index 0000000000000000000000000000000000000000..a00dc22e5e0f7b506d089858b7ed281d3ed6092b Binary files /dev/null and b/Assets/ETSI.ARF/ARF World Storage API/Images/cloud.png differ diff --git a/Assets/ETSI.ARF/ARF World Storage API/Images/cloud.png.meta b/Assets/ETSI.ARF/ARF World Storage API/Images/cloud.png.meta new file mode 100644 index 0000000000000000000000000000000000000000..d55875b36fcabd3b68f507a419bf97935937257b --- /dev/null +++ b/Assets/ETSI.ARF/ARF World Storage API/Images/cloud.png.meta @@ -0,0 +1,98 @@ +fileFormatVersion: 2 +guid: 8338d2b625f22b44095330be071b8e56 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ETSI.ARF/ARF World Storage API/Images/warning.png b/Assets/ETSI.ARF/ARF World Storage API/Images/warning.png new file mode 100644 index 0000000000000000000000000000000000000000..a989284db594278ae478f2e8cb1b8cafa036a229 Binary files /dev/null and b/Assets/ETSI.ARF/ARF World Storage API/Images/warning.png differ diff --git a/Assets/ETSI.ARF/ARF World Storage API/Images/warning.png.meta b/Assets/ETSI.ARF/ARF World Storage API/Images/warning.png.meta new file mode 100644 index 0000000000000000000000000000000000000000..d01302454a5d82fa883c4da0d0112d955b8d3474 --- /dev/null +++ b/Assets/ETSI.ARF/ARF World Storage API/Images/warning.png.meta @@ -0,0 +1,98 @@ +fileFormatVersion: 2 +guid: 2add88abf0fc00043bfb7863d59d3aa8 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ETSI.ARF/ARF World Storage API/Models/knabe_simplified.obj.meta b/Assets/ETSI.ARF/ARF World Storage API/Models/knabe_simplified.obj.meta deleted file mode 100644 index b83ebe5f64cb2e9956559ebec02f7bb963fb1d00..0000000000000000000000000000000000000000 --- a/Assets/ETSI.ARF/ARF World Storage API/Models/knabe_simplified.obj.meta +++ /dev/null @@ -1,105 +0,0 @@ -fileFormatVersion: 2 -guid: a88506592fee52a4d976c4ba6bbe454d -ModelImporter: - serializedVersion: 21202 - internalIDToNameTable: [] - externalObjects: {} - materials: - materialImportMode: 0 - materialName: 0 - materialSearch: 1 - materialLocation: 1 - animations: - legacyGenerateAnimations: 4 - bakeSimulation: 0 - resampleCurves: 1 - optimizeGameObjects: 0 - removeConstantScaleCurves: 1 - motionNodeName: - rigImportErrors: - rigImportWarnings: - animationImportErrors: - animationImportWarnings: - animationRetargetingWarnings: - animationDoRetargetingWarnings: 0 - importAnimatedCustomProperties: 0 - importConstraints: 0 - animationCompression: 1 - animationRotationError: 0.5 - animationPositionError: 0.5 - animationScaleError: 0.5 - animationWrapMode: 0 - extraExposedTransformPaths: [] - extraUserProperties: [] - clipAnimations: [] - isReadable: 0 - meshes: - lODScreenPercentages: [] - globalScale: 0.001 - meshCompression: 0 - addColliders: 0 - useSRGBMaterialColor: 1 - sortHierarchyByName: 1 - importVisibility: 1 - importBlendShapes: 1 - importCameras: 1 - importLights: 1 - nodeNameCollisionStrategy: 1 - fileIdsGeneration: 2 - swapUVChannels: 0 - generateSecondaryUV: 0 - useFileUnits: 1 - keepQuads: 0 - weldVertices: 1 - bakeAxisConversion: 0 - preserveHierarchy: 0 - skinWeightsMode: 0 - maxBonesPerVertex: 4 - minBoneWeight: 0.001 - optimizeBones: 0 - meshOptimizationFlags: -1 - indexFormat: 0 - secondaryUVAngleDistortion: 8 - secondaryUVAreaDistortion: 15.000001 - secondaryUVHardAngle: 88 - secondaryUVMarginMethod: 1 - secondaryUVMinLightmapResolution: 40 - secondaryUVMinObjectScale: 1 - secondaryUVPackMargin: 4 - useFileScale: 1 - tangentSpace: - normalSmoothAngle: 60 - normalImportMode: 0 - tangentImportMode: 3 - normalCalculationMode: 4 - legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0 - blendShapeNormalImportMode: 1 - normalSmoothingSource: 0 - referencedClips: [] - importAnimation: 0 - humanDescription: - serializedVersion: 3 - human: [] - skeleton: [] - armTwist: 0.5 - foreArmTwist: 0.5 - upperLegTwist: 0.5 - legTwist: 0.5 - armStretch: 0.05 - legStretch: 0.05 - feetSpacing: 0 - globalScale: 0.001 - rootMotionBoneName: - hasTranslationDoF: 0 - hasExtraRoot: 0 - skeletonHasParents: 1 - lastHumanDescriptionAvatarSource: {instanceID: 0} - autoGenerateAvatarMappingIfUnspecified: 1 - animationType: 2 - humanoidOversampling: 1 - avatarSetup: 0 - addHumanoidExtraRootOnlyWhenUsingAvatar: 1 - additionalBone: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/ETSI.ARF/ARF World Storage API/World Storage/LocalHost8080.asset b/Assets/ETSI.ARF/ARF World Storage API/World Storage/LocalHost8080.asset new file mode 100644 index 0000000000000000000000000000000000000000..d00574d15efa157ab1299a9cf17b9e26af1de824 --- /dev/null +++ b/Assets/ETSI.ARF/ARF World Storage API/World Storage/LocalHost8080.asset @@ -0,0 +1,19 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e4b7be4c33f68d0418c3b4e1a7053d91, type: 3} + m_Name: LocalHost8080 + m_EditorClassIdentifier: + serverName: Local hosted World Storage + company: b<>com + basePath: http://10.55.11.9 + port: 8080 + currentUser: {fileID: 11400000, guid: c0696089e4a855b46ad490437919b1e8, type: 2} diff --git a/Assets/ETSI.ARF/ARF World Storage API/World Storage/LocalHost8080.asset.meta b/Assets/ETSI.ARF/ARF World Storage API/World Storage/LocalHost8080.asset.meta new file mode 100644 index 0000000000000000000000000000000000000000..d979dc502f9499f33ff9b43ccc4bef65948c8d65 --- /dev/null +++ b/Assets/ETSI.ARF/ARF World Storage API/World Storage/LocalHost8080.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3a9ba82f4e8dd124ca2b005861c64d01 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ETSI.ARF/ARF World Storage API/World Storage/LocalHost8081.asset b/Assets/ETSI.ARF/ARF World Storage API/World Storage/LocalHost8081.asset new file mode 100644 index 0000000000000000000000000000000000000000..66e0b5042d3c94a77c747a6b66c6404462478bf0 --- /dev/null +++ b/Assets/ETSI.ARF/ARF World Storage API/World Storage/LocalHost8081.asset @@ -0,0 +1,19 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e4b7be4c33f68d0418c3b4e1a7053d91, type: 3} + m_Name: LocalHost8081 + m_EditorClassIdentifier: + serverName: local hosted 8081 + company: b<>com + basePath: http://10.55.11.9 + port: 8081 + currentUser: {fileID: 11400000, guid: c0696089e4a855b46ad490437919b1e8, type: 2} diff --git a/Assets/ETSI.ARF/ARF World Storage API/World Storage/LocalHost8081.asset.meta b/Assets/ETSI.ARF/ARF World Storage API/World Storage/LocalHost8081.asset.meta new file mode 100644 index 0000000000000000000000000000000000000000..b86dce60532dd1b5b3deaf953ae03c1f9c9a1892 --- /dev/null +++ b/Assets/ETSI.ARF/ARF World Storage API/World Storage/LocalHost8081.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 777684ed8f62c9d408a1813e8382c676 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Images/GraphEditor.png b/Images/GraphEditor.png new file mode 100644 index 0000000000000000000000000000000000000000..77361699ed8831c1902b7a3450cb159af145adc9 Binary files /dev/null and b/Images/GraphEditor.png differ diff --git a/Images/WorldStorageObject.png b/Images/WorldStorageObject.png new file mode 100644 index 0000000000000000000000000000000000000000..ab57d380c3b22a8b4b96274ac0f255b8bced60ec Binary files /dev/null and b/Images/WorldStorageObject.png differ diff --git a/Packages/unity-world-storage-package b/Packages/unity-world-storage-package index 688bf209c3e6d27d10782b2583b0e9c8edea15c7..c8406f18a9f789d4cc0eb2ef995d274797ea4051 160000 --- a/Packages/unity-world-storage-package +++ b/Packages/unity-world-storage-package @@ -1 +1 @@ -Subproject commit 688bf209c3e6d27d10782b2583b0e9c8edea15c7 +Subproject commit c8406f18a9f789d4cc0eb2ef995d274797ea4051 diff --git a/ProjectSettings/EditorSettings.asset b/ProjectSettings/EditorSettings.asset index de5d0b2dff999c2fb46455e5a995c4dbebc8c727..621c5458599cc89fedd54048a072cc35b8fb6171 100644 --- a/ProjectSettings/EditorSettings.asset +++ b/ProjectSettings/EditorSettings.asset @@ -4,7 +4,6 @@ EditorSettings: m_ObjectHideFlags: 0 serializedVersion: 11 - m_ExternalVersionControlSupport: Visible Meta Files m_SerializationMode: 2 m_LineEndingsForNewScripts: 0 m_DefaultBehaviorMode: 0 @@ -12,19 +11,32 @@ EditorSettings: m_PrefabUIEnvironment: {fileID: 0} m_SpritePackerMode: 0 m_SpritePackerPaddingPower: 1 + m_Bc7TextureCompressor: 0 m_EtcTextureCompressorBehavior: 1 m_EtcTextureFastCompressor: 1 m_EtcTextureNormalCompressor: 2 m_EtcTextureBestCompressor: 4 m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;rsp;asmref m_ProjectGenerationRootNamespace: - m_CollabEditorSettings: - inProgressEnabled: 1 m_EnableTextureStreamingInEditMode: 1 m_EnableTextureStreamingInPlayMode: 1 m_AsyncShaderCompilation: 1 + m_CachingShaderPreprocessor: 1 + m_PrefabModeAllowAutoSave: 1 m_EnterPlayModeOptionsEnabled: 0 m_EnterPlayModeOptions: 3 - m_ShowLightmapResolutionOverlay: 1 + m_GameObjectNamingDigits: 1 + m_GameObjectNamingScheme: 0 + m_AssetNamingUsesSpace: 1 m_UseLegacyProbeSampleCount: 0 - m_SerializeInlineMappingsOnOneLine: 1 \ No newline at end of file + m_SerializeInlineMappingsOnOneLine: 1 + m_DisableCookiesInLightmapper: 0 + m_AssetPipelineMode: 1 + m_RefreshImportMode: 0 + m_CacheServerMode: 0 + m_CacheServerEndpoint: + m_CacheServerNamespacePrefix: default + m_CacheServerEnableDownload: 1 + m_CacheServerEnableUpload: 1 + m_CacheServerEnableAuth: 0 + m_CacheServerEnableTls: 0 diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset index e29f9aa0df1eaf8d6145d251ec40fad2ccab8568..cb14926b1ea41efba0e033bbc94eb0386827302e 100644 --- a/ProjectSettings/ProjectSettings.asset +++ b/ProjectSettings/ProjectSettings.asset @@ -152,7 +152,8 @@ PlayerSettings: resolutionScalingMode: 0 androidSupportedAspectRatio: 1 androidMaxAspectRatio: 2.1 - applicationIdentifier: {} + applicationIdentifier: + Standalone: com.DefaultCompany.My-project buildNumber: Standalone: 0 iPhone: 0 diff --git a/README.md b/README.md index b3fe2052b05b8cb7d53c46e09e9dd778d765cb96..9b934674617a0559b98c391cfb720214c0d3e2c2 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,49 @@ +*This repository is part of the outcomes of the Specialist Task Force 620 focusing on the authoring of a World Representation as part of the ETSI ISG Augmented Reality Framework architecture (https://www.etsi.org/deliver/etsi_gs/ARF/001_099/003/01.01.01_60/gs_ARF003v010101p.pdf).* +*The set of the World Representation authoring components includes:* + +*• The C++ and C# source code for servers and clients generated from OpenAPI available here (https://forge.etsi.org/rep/arf/arf005)* + +*• A Unity plugin and a Unity editor for authoring and accessing a World Representation hosted on a World Storage server.* + +*All these components are available under the ETSI Labs group “World Storage API Helpersâ€: https://labs.etsi.org/rep/arf/world-storage-api-helpers* + +*If you wish to contribute to this project or any other projects in the context of the [ETSI ISG Augmented Reality Framework architecture](https://www.etsi.org/committee/1420-arf), please refer to the ["How to get involved in an ISG" section on the ETSI website](https://www.etsi.org/how-to-get-involved-in-an-isg)* + +--- + # Setting RESTful package Please set up first the path in the Unity manifest.json for the 'Unity World Storage Package' correctly! ---- +This repo contains submodules corresponding to REST libraries used in the Unity project. + +Once the git repo is cloned, you need to init and update the submodules through git commands: + + git submodule init + git submodule update + +or clone the repo updating the submodules directly: + + git clone --recurse-submodules https://labs.etsi.org/rep/arf/world-storage-api-helpers/unity-world-storage-editor.git + +Once it's done, you can open your project from the Unity Hub, the project was coded in Unity 2021.3.0 and # Description of UI / editor functions +This Unity Editor module allows the user to author the World Storage through various ways. To interact with a server hosting an implementation of the World Storage, the user first must create an Unity object "World Storage Server" via the contextual menu (Create -> ARF World Storage -> Create Server) and then fill the corresponding informations (name, URL, port...). + + +## World Storage Window + +Through the Unity inspector of the World Storage Server, the user can click on the `Open World Storage Window...` button. This opens the authoring tool for the corresponding World Storage. + +In this editor, the user has access to... +TODO + +## World Graph Window + + +The second tool of this repo is the World Graph Window. From the top toolbar the user has access to the `ARFWolrdStorage` option, from which he can click on the `Edit Graph...` option. This will open the Graph Editor Window. The user can then select the desired World Storage server to interact with. -xxx +After fetching all elements, The user can move them around in the graph, create new ones, modify or delete them. +All changes are done locally, in order to push the modifications to the server, the user has the option to save all elements in the contextual menu or save specific elements in their custom inspectors. Each element type has its custom inspector from which you can modify their attributes and discard or save local changes. diff --git a/UserSettings/Layouts/CurrentMaximizeLayout.dwlt b/UserSettings/Layouts/CurrentMaximizeLayout.dwlt new file mode 100644 index 0000000000000000000000000000000000000000..0658840717aa4f61cd2d399c5b0ee8fa6bc7c9b1 --- /dev/null +++ b/UserSettings/Layouts/CurrentMaximizeLayout.dwlt @@ -0,0 +1,910 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &1 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_Children: + - {fileID: 3} + - {fileID: 13} + m_Position: + serializedVersion: 2 + x: 0 + y: 30 + width: 1600 + height: 768 + m_MinSize: {x: 300, y: 200} + m_MaxSize: {x: 24288, y: 16192} + vertical: 0 + controlID: 28 +--- !u!114 &2 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12013, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 200, y: 200} + m_MaxSize: {x: 4000, y: 4000} + m_TitleContent: + m_Text: Scene + m_Image: {fileID: 8634526014445323508, guid: 0000000000000000d000000000000000, type: 0} + m_Tooltip: + m_Pos: + serializedVersion: 2 + x: 302.5 + y: 72 + width: 917.5 + height: 434 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: + - dockPosition: 0 + containerId: overlay-toolbar__top + floating: 0 + collapsed: 0 + displayed: 1 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: -98, y: -26} + snapCorner: 3 + id: Tool Settings + index: 0 + layout: 1 + - dockPosition: 0 + containerId: overlay-toolbar__top + floating: 0 + collapsed: 0 + displayed: 1 + snapOffset: {x: -141, y: 149} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 1 + id: unity-grid-and-snap-toolbar + index: 1 + layout: 1 + - dockPosition: 1 + containerId: overlay-toolbar__top + floating: 0 + collapsed: 0 + displayed: 1 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: unity-scene-view-toolbar + index: 0 + layout: 1 + - dockPosition: 1 + containerId: overlay-toolbar__top + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 1 + id: unity-search-toolbar + index: 1 + layout: 1 + - dockPosition: 0 + containerId: overlay-container--left + floating: 0 + collapsed: 0 + displayed: 1 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: unity-transform-toolbar + index: 0 + layout: 2 + - dockPosition: 0 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 1 + snapOffset: {x: 67.5, y: 86} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Orientation + index: 0 + layout: 4 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Light Settings + index: 0 + layout: 4 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Camera + index: 1 + layout: 4 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Cloth Constraints + index: 2 + layout: 4 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Cloth Collisions + index: 3 + layout: 4 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Navmesh Display + index: 4 + layout: 4 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Agent Display + index: 5 + layout: 4 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Obstacle Display + index: 6 + layout: 4 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Occlusion Culling + index: 7 + layout: 4 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Physics Debugger + index: 8 + layout: 4 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Scene Visibility + index: 9 + layout: 4 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Particles + index: 10 + layout: 4 + m_WindowGUID: cc27987af1a868c49b0894db9c0f5429 + m_Gizmos: 1 + m_OverrideSceneCullingMask: 6917529027641081856 + m_SceneIsLit: 1 + m_SceneLighting: 1 + m_2DMode: 0 + m_isRotationLocked: 0 + m_PlayAudio: 0 + m_AudioPlay: 0 + m_Position: + m_Target: {x: 1.3304825, y: 3.9150038, z: -3.6284218} + speed: 2 + m_Value: {x: 0, y: 0, z: 0} + m_RenderMode: 0 + m_CameraMode: + drawMode: 0 + name: Shaded + section: Shading Mode + m_ValidateTrueMetals: 0 + m_DoValidateTrueMetals: 0 + m_ExposureSliderValue: 0 + m_SceneViewState: + m_AlwaysRefresh: 0 + showFog: 0 + showSkybox: 0 + showFlares: 0 + showImageEffects: 1 + showParticleSystems: 1 + showVisualEffectGraphs: 1 + m_FxEnabled: 1 + m_Grid: + xGrid: + m_Fade: + m_Target: 0 + speed: 2 + m_Value: 0 + m_Color: {r: 0.5, g: 0.5, b: 0.5, a: 0.4} + m_Pivot: {x: 0, y: 0, z: 0} + m_Size: {x: 0, y: 0} + yGrid: + m_Fade: + m_Target: 1 + speed: 2 + m_Value: 1 + m_Color: {r: 0.5, g: 0.5, b: 0.5, a: 0.4} + m_Pivot: {x: 0, y: 0, z: 0} + m_Size: {x: 1, y: 1} + zGrid: + m_Fade: + m_Target: 0 + speed: 2 + m_Value: 0 + m_Color: {r: 0.5, g: 0.5, b: 0.5, a: 0.4} + m_Pivot: {x: 0, y: 0, z: 0} + m_Size: {x: 0, y: 0} + m_ShowGrid: 1 + m_GridAxis: 1 + m_gridOpacity: 0.5 + m_Rotation: + m_Target: {x: -0.037954368, y: 0.9214571, z: -0.09320772, w: -0.37521872} + speed: 2 + m_Value: {x: -0.08717229, y: 0.89959055, z: -0.21045254, w: -0.3726226} + m_Size: + m_Target: 10 + speed: 2 + m_Value: 10 + m_Ortho: + m_Target: 0 + speed: 2 + m_Value: 0 + m_CameraSettings: + m_Speed: 1 + m_SpeedNormalized: 0.5 + m_SpeedMin: 0.001 + m_SpeedMax: 2 + m_EasingEnabled: 1 + m_EasingDuration: 0.4 + m_AccelerationEnabled: 1 + m_FieldOfViewHorizontalOrVertical: 60 + m_NearClip: 0.03 + m_FarClip: 10000 + m_DynamicClip: 1 + m_OcclusionCulling: 0 + m_LastSceneViewRotation: {x: 0, y: 0, z: 0, w: 0} + m_LastSceneViewOrtho: 0 + m_ReplacementShader: {fileID: 0} + m_ReplacementString: + m_SceneVisActive: 1 + m_LastLockedObject: {fileID: 0} + m_ViewIsLockedToObject: 0 +--- !u!114 &3 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_Children: + - {fileID: 4} + - {fileID: 10} + m_Position: + serializedVersion: 2 + x: 0 + y: 0 + width: 1222 + height: 768 + m_MinSize: {x: 200, y: 200} + m_MaxSize: {x: 16192, y: 16192} + vertical: 1 + controlID: 29 +--- !u!114 &4 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_Children: + - {fileID: 5} + - {fileID: 7} + m_Position: + serializedVersion: 2 + x: 0 + y: 0 + width: 1222 + height: 455 + m_MinSize: {x: 200, y: 100} + m_MaxSize: {x: 16192, y: 8096} + vertical: 0 + controlID: 30 +--- !u!114 &5 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_Children: [] + m_Position: + serializedVersion: 2 + x: 0 + y: 0 + width: 302.5 + height: 455 + m_MinSize: {x: 201, y: 221} + m_MaxSize: {x: 4001, y: 4021} + m_ActualView: {fileID: 6} + m_Panes: + - {fileID: 6} + m_Selected: 0 + m_LastSelected: 0 +--- !u!114 &6 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12061, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 200, y: 200} + m_MaxSize: {x: 4000, y: 4000} + m_TitleContent: + m_Text: Hierarchy + m_Image: {fileID: -3734745235275155857, guid: 0000000000000000d000000000000000, type: 0} + m_Tooltip: + m_Pos: + serializedVersion: 2 + x: 0 + y: 72 + width: 301.5 + height: 434 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] + m_SceneHierarchy: + m_TreeViewState: + scrollPos: {x: 0, y: 0} + m_SelectedIDs: + m_LastClickedID: 0 + m_ExpandedIDs: 38fbffff + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 0 + m_ClientGUIView: {fileID: 0} + m_SearchString: + m_ExpandedScenes: [] + m_CurrenRootInstanceID: 0 + m_LockTracker: + m_IsLocked: 0 + m_CurrentSortingName: TransformSorting + m_WindowGUID: 4c969a2b90040154d917609493e03593 +--- !u!114 &7 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} + m_Name: SceneView + m_EditorClassIdentifier: + m_Children: [] + m_Position: + serializedVersion: 2 + x: 302.5 + y: 0 + width: 919.5 + height: 455 + m_MinSize: {x: 202, y: 221} + m_MaxSize: {x: 4002, y: 4021} + m_ActualView: {fileID: 2} + m_Panes: + - {fileID: 2} + - {fileID: 8} + - {fileID: 9} + m_Selected: 0 + m_LastSelected: 2 +--- !u!114 &8 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12015, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 200, y: 200} + m_MaxSize: {x: 4000, y: 4000} + m_TitleContent: + m_Text: Game + m_Image: {fileID: 4621777727084837110, guid: 0000000000000000d000000000000000, type: 0} + m_Tooltip: + m_Pos: + serializedVersion: 2 + x: 507 + y: 94 + width: 1532 + height: 790 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] + m_SerializedViewNames: [] + m_SerializedViewValues: [] + m_PlayModeViewName: GameView + m_ShowGizmos: 0 + m_TargetDisplay: 0 + m_ClearColor: {r: 0, g: 0, b: 0, a: 0} + m_TargetSize: {x: 1532, y: 769} + m_TextureFilterMode: 0 + m_TextureHideFlags: 61 + m_RenderIMGUI: 0 + m_EnterPlayModeBehavior: 0 + m_UseMipMap: 0 + m_VSyncEnabled: 0 + m_Gizmos: 0 + m_Stats: 0 + m_SelectedSizes: 00000000000000000000000000000000000000000000000000000000000000000000000000000000 + m_ZoomArea: + m_HRangeLocked: 0 + m_VRangeLocked: 0 + hZoomLockedByDefault: 0 + vZoomLockedByDefault: 0 + m_HBaseRangeMin: -383 + m_HBaseRangeMax: 383 + m_VBaseRangeMin: -197.5 + m_VBaseRangeMax: 197.5 + m_HAllowExceedBaseRangeMin: 1 + m_HAllowExceedBaseRangeMax: 1 + m_VAllowExceedBaseRangeMin: 1 + m_VAllowExceedBaseRangeMax: 1 + m_ScaleWithWindow: 0 + m_HSlider: 0 + m_VSlider: 0 + m_IgnoreScrollWheelUntilClicked: 0 + m_EnableMouseInput: 1 + m_EnableSliderZoomHorizontal: 0 + m_EnableSliderZoomVertical: 0 + m_UniformScale: 1 + m_UpDirection: 1 + m_DrawArea: + serializedVersion: 2 + x: 0 + y: 0 + width: 1532 + height: 790 + m_Scale: {x: 2, y: 2} + m_Translation: {x: 766, y: 395} + m_MarginLeft: 0 + m_MarginRight: 0 + m_MarginTop: 0 + m_MarginBottom: 0 + m_LastShownAreaInsideMargins: + serializedVersion: 2 + x: -383 + y: -197.5 + width: 766 + height: 395 + m_MinimalGUI: 1 + m_defaultScale: 2 + m_LastWindowPixelSize: {x: 3064, y: 1580} + m_ClearInEditMode: 1 + m_NoCameraWarning: 1 + m_LowResolutionForAspectRatios: 01000000000000000000 + m_XRRenderMode: 0 + m_RenderTexture: {fileID: 0} +--- !u!114 &9 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2c1a0c92306453d46897c1af6cb5c2f9, type: 3} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 100, y: 100} + m_MaxSize: {x: 4000, y: 4000} + m_TitleContent: + m_Text: Graph Editor + m_Image: {fileID: 0} + m_Tooltip: + m_Pos: + serializedVersion: 2 + x: 302.5 + y: 72 + width: 917.5 + height: 434 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] + worldStorageServer: {fileID: 11400000, guid: 3a9ba82f4e8dd124ca2b005861c64d01, type: 2} + worldStorageUser: {fileID: 11400000, guid: c0696089e4a855b46ad490437919b1e8, type: 2} +--- !u!114 &10 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} + m_Name: ProjectBrowser + m_EditorClassIdentifier: + m_Children: [] + m_Position: + serializedVersion: 2 + x: 0 + y: 455 + width: 1222 + height: 313 + m_MinSize: {x: 231, y: 271} + m_MaxSize: {x: 10001, y: 10021} + m_ActualView: {fileID: 11} + m_Panes: + - {fileID: 11} + - {fileID: 12} + m_Selected: 0 + m_LastSelected: 1 +--- !u!114 &11 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12014, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 230, y: 250} + m_MaxSize: {x: 10000, y: 10000} + m_TitleContent: + m_Text: Project + m_Image: {fileID: -5179483145760003458, guid: 0000000000000000d000000000000000, type: 0} + m_Tooltip: + m_Pos: + serializedVersion: 2 + x: 0 + y: 527 + width: 1221 + height: 292 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] + m_SearchFilter: + m_NameFilter: + m_ClassNames: [] + m_AssetLabels: [] + m_AssetBundleNames: [] + m_VersionControlStates: [] + m_SoftLockControlStates: [] + m_ReferencingInstanceIDs: + m_SceneHandles: + m_ShowAllHits: 0 + m_SkipHidden: 0 + m_SearchArea: 1 + m_Folders: + - Assets + m_Globs: [] + m_OriginalText: + m_ViewMode: 1 + m_StartGridSize: 64 + m_LastFolders: + - Assets + m_LastFoldersGridSize: -1 + m_LastProjectPath: C:\Dev\unity-world-storage-editor + m_LockTracker: + m_IsLocked: 0 + m_FolderTreeState: + scrollPos: {x: 0, y: 0} + m_SelectedIDs: 484d0000 + m_LastClickedID: 19784 + m_ExpandedIDs: 00000000484d00004a4d00004c4d00004e4d000000ca9a3bffffff7f + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 1 + m_ClientGUIView: {fileID: 0} + m_SearchString: + m_CreateAssetUtility: + m_EndAction: {fileID: 0} + m_InstanceID: 0 + m_Path: + m_Icon: {fileID: 0} + m_ResourceFile: + m_AssetTreeState: + scrollPos: {x: 0, y: 0} + m_SelectedIDs: + m_LastClickedID: 0 + m_ExpandedIDs: 00000000484d00004a4d00004c4d00004e4d0000 + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 1 + m_ClientGUIView: {fileID: 0} + m_SearchString: + m_CreateAssetUtility: + m_EndAction: {fileID: 0} + m_InstanceID: 0 + m_Path: + m_Icon: {fileID: 0} + m_ResourceFile: + m_ListAreaState: + m_SelectedInstanceIDs: + m_LastClickedInstanceID: 0 + m_HadKeyboardFocusLastEvent: 0 + m_ExpandedInstanceIDs: c6230000 + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 1 + m_ClientGUIView: {fileID: 0} + m_CreateAssetUtility: + m_EndAction: {fileID: 0} + m_InstanceID: 0 + m_Path: + m_Icon: {fileID: 0} + m_ResourceFile: + m_NewAssetIndexInList: -1 + m_ScrollPosition: {x: 0, y: 0} + m_GridSize: 64 + m_SkipHiddenPackages: 0 + m_DirectoriesAreaWidth: 207 +--- !u!114 &12 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12003, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 100, y: 100} + m_MaxSize: {x: 4000, y: 4000} + m_TitleContent: + m_Text: Console + m_Image: {fileID: -4950941429401207979, guid: 0000000000000000d000000000000000, type: 0} + m_Tooltip: + m_Pos: + serializedVersion: 2 + x: 2249 + y: 726.5 + width: 920 + height: 250 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] +--- !u!114 &13 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} + m_Name: GraphEditorWindow + m_EditorClassIdentifier: + m_Children: [] + m_Position: + serializedVersion: 2 + x: 1222 + y: 0 + width: 378 + height: 768 + m_MinSize: {x: 101, y: 121} + m_MaxSize: {x: 4001, y: 4021} + m_ActualView: {fileID: 15} + m_Panes: + - {fileID: 14} + - {fileID: 15} + m_Selected: 1 + m_LastSelected: 0 +--- !u!114 &14 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12019, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 275, y: 50} + m_MaxSize: {x: 4000, y: 4000} + m_TitleContent: + m_Text: Inspector + m_Image: {fileID: -440750813802333266, guid: 0000000000000000d000000000000000, type: 0} + m_Tooltip: + m_Pos: + serializedVersion: 2 + x: 1222 + y: 72 + width: 377 + height: 747 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] + m_ObjectsLockedBeforeSerialization: [] + m_InstanceIDsLockedBeforeSerialization: + m_PreviewResizer: + m_CachedPref: 160 + m_ControlHash: -371814159 + m_PrefName: Preview_InspectorPreview + m_LastInspectedObjectInstanceID: -1 + m_LastVerticalScrollValue: 0 + m_GlobalObjectId: + m_InspectorMode: 0 + m_LockTracker: + m_IsLocked: 0 + m_PreviewWindow: {fileID: 0} +--- !u!114 &15 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e219817d65c8b1f40ad85e6185e89e92, type: 3} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 100, y: 100} + m_MaxSize: {x: 4000, y: 4000} + m_TitleContent: + m_Text: Element Editor + m_Image: {fileID: 0} + m_Tooltip: + m_Pos: + serializedVersion: 2 + x: 1222 + y: 72 + width: 377 + height: 747 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] + type: 2 + local_size: {x: 0, y: 0, z: 0} + local_rot: {x: 326.0875, y: 321.98138, z: 321.98138} + local_pos: {x: 0, y: 0, z: 0} diff --git a/UserSettings/Layouts/default-2021.dwlt b/UserSettings/Layouts/default-2021.dwlt index 195f50d538270ece9b6be97d6483cdeea1ee8e91..cacd903f7aa5f33fca8c696523747f3e54b8861d 100644 --- a/UserSettings/Layouts/default-2021.dwlt +++ b/UserSettings/Layouts/default-2021.dwlt @@ -10,8 +10,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 12004, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_PixelRect: serializedVersion: 2 x: 448.44446 @@ -209,8 +209,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Children: - {fileID: 16} - {fileID: 10} @@ -234,8 +234,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Children: [] m_Position: serializedVersion: 2 @@ -260,8 +260,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Children: [] m_Position: serializedVersion: 2 @@ -287,7 +287,7 @@ MonoBehaviour: m_EditorHideFlags: 1 m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} m_Name: ProjectBrowser - m_EditorClassIdentifier: + m_EditorClassIdentifier: m_Children: [] m_Position: serializedVersion: 2 @@ -312,8 +312,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12008, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Children: - {fileID: 14} - {fileID: 5} @@ -340,8 +340,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12011, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Children: [] m_Position: serializedVersion: 2 @@ -362,8 +362,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12042, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Children: [] m_Position: serializedVersion: 2 @@ -383,8 +383,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Children: - {fileID: 17} - {fileID: 8} @@ -408,8 +408,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Children: - {fileID: 11} - {fileID: 18} @@ -434,8 +434,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} - m_Name: SceneView - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_Children: [] m_Position: serializedVersion: 2 @@ -520,8 +520,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12014, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_MinSize: {x: 230, y: 250} m_MaxSize: {x: 10000, y: 10000} m_TitleContent: @@ -535,27 +535,23 @@ MonoBehaviour: width: 706.55554 height: 274.33337 m_ViewDataDictionary: {fileID: 0} - m_OverlayCanvas: - m_LastAppliedPresetName: Default - m_SaveData: [] m_SearchFilter: - m_NameFilter: + m_NameFilter: m_ClassNames: [] m_AssetLabels: [] m_AssetBundleNames: [] m_VersionControlStates: [] m_SoftLockControlStates: [] - m_ReferencingInstanceIDs: - m_SceneHandles: + m_ReferencingInstanceIDs: + m_SceneHandles: m_ShowAllHits: 0 m_SkipHidden: 0 m_SearchArea: 1 m_Folders: - Assets/ETSI.ARF/ARF World Storage API/World Storage m_Globs: [] - m_OriginalText: m_ViewMode: 1 - m_StartGridSize: 16 + m_StartGridSize: 64 m_LastFolders: - Assets/ETSI.ARF/ARF World Storage API/World Storage m_LastFoldersGridSize: 16 @@ -569,8 +565,8 @@ MonoBehaviour: m_ExpandedIDs: 00000000b84d0000ba4d0000bc4d0000be4d0000c04d0000c24d0000c44d000000ca9a3b m_RenameOverlay: m_UserAcceptedRename: 0 - m_Name: - m_OriginalName: + m_Name: + m_OriginalName: m_EditFieldRect: serializedVersion: 2 x: 0 @@ -587,18 +583,18 @@ MonoBehaviour: m_CreateAssetUtility: m_EndAction: {fileID: 0} m_InstanceID: 0 - m_Path: + m_Path: m_Icon: {fileID: 0} - m_ResourceFile: + m_ResourceFile: m_AssetTreeState: scrollPos: {x: 0, y: 0} - m_SelectedIDs: + m_SelectedIDs: m_LastClickedID: 0 m_ExpandedIDs: 00000000b84d0000ba4d0000bc4d0000be4d0000c04d0000c24d0000c44d0000 m_RenameOverlay: m_UserAcceptedRename: 0 - m_Name: - m_OriginalName: + m_Name: + m_OriginalName: m_EditFieldRect: serializedVersion: 2 x: 0 @@ -611,22 +607,22 @@ MonoBehaviour: m_OriginalEventType: 11 m_IsRenamingFilename: 1 m_ClientGUIView: {fileID: 0} - m_SearchString: + m_SearchString: m_CreateAssetUtility: m_EndAction: {fileID: 0} m_InstanceID: 0 - m_Path: + m_Path: m_Icon: {fileID: 0} - m_ResourceFile: + m_ResourceFile: m_ListAreaState: - m_SelectedInstanceIDs: + m_SelectedInstanceIDs: m_LastClickedInstanceID: 0 m_HadKeyboardFocusLastEvent: 1 m_ExpandedInstanceIDs: c6230000de4b000000000000 m_RenameOverlay: m_UserAcceptedRename: 0 - m_Name: - m_OriginalName: + m_Name: + m_OriginalName: m_EditFieldRect: serializedVersion: 2 x: 0 @@ -642,12 +638,12 @@ MonoBehaviour: m_CreateAssetUtility: m_EndAction: {fileID: 0} m_InstanceID: 0 - m_Path: + m_Path: m_Icon: {fileID: 0} - m_ResourceFile: + m_ResourceFile: m_NewAssetIndexInList: -1 m_ScrollPosition: {x: 0, y: 0} - m_GridSize: 16 + m_GridSize: 64 m_SkipHiddenPackages: 0 m_DirectoriesAreaWidth: 359.1111 --- !u!114 &22 @@ -660,8 +656,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12019, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_MinSize: {x: 275, y: 50} m_MaxSize: {x: 4000, y: 4000} m_TitleContent: @@ -675,19 +671,16 @@ MonoBehaviour: width: 333.66663 height: 913.44446 m_ViewDataDictionary: {fileID: 0} - m_OverlayCanvas: - m_LastAppliedPresetName: Default - m_SaveData: [] m_ObjectsLockedBeforeSerialization: [] - m_InstanceIDsLockedBeforeSerialization: + m_InstanceIDsLockedBeforeSerialization: m_PreviewResizer: m_CachedPref: 160 m_ControlHash: -371814159 m_PrefName: Preview_InspectorPreview m_LastInspectedObjectInstanceID: -1 m_LastVerticalScrollValue: 0 - m_GlobalObjectId: - m_InspectorMode: 0 + m_AssetGUID: + m_InstanceID: 0 m_LockTracker: m_IsLocked: 0 m_PreviewWindow: {fileID: 0} @@ -701,8 +694,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12061, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_MinSize: {x: 200, y: 200} m_MaxSize: {x: 4000, y: 4000} m_TitleContent: @@ -716,9 +709,6 @@ MonoBehaviour: width: 308.33334 height: 618.1111 m_ViewDataDictionary: {fileID: 0} - m_OverlayCanvas: - m_LastAppliedPresetName: Default - m_SaveData: [] m_SceneHierarchy: m_TreeViewState: scrollPos: {x: 0, y: 0} @@ -727,8 +717,8 @@ MonoBehaviour: m_ExpandedIDs: 34fbffff284b0000964b0000a64c0000 m_RenameOverlay: m_UserAcceptedRename: 0 - m_Name: - m_OriginalName: + m_Name: + m_OriginalName: m_EditFieldRect: serializedVersion: 2 x: 0 @@ -740,8 +730,8 @@ MonoBehaviour: m_IsRenaming: 0 m_OriginalEventType: 11 m_IsRenamingFilename: 0 - m_ClientGUIView: {fileID: 11} - m_SearchString: + m_ClientGUIView: {fileID: 0} + m_SearchString: m_ExpandedScenes: [] m_CurrenRootInstanceID: 0 m_LockTracker: @@ -758,8 +748,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12013, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_MinSize: {x: 200, y: 200} m_MaxSize: {x: 4000, y: 4000} m_TitleContent: @@ -985,21 +975,20 @@ MonoBehaviour: m_DoValidateTrueMetals: 0 m_ExposureSliderValue: 0 m_SceneViewState: - m_AlwaysRefresh: 0 showFog: 1 + showMaterialUpdate: 0 showSkybox: 1 showFlares: 1 showImageEffects: 1 showParticleSystems: 1 showVisualEffectGraphs: 1 - m_FxEnabled: 1 m_Grid: xGrid: m_Fade: m_Target: 0 speed: 2 m_Value: 0 - m_Color: {r: 0, g: 1, b: 0, a: 0.4} + m_Color: {r: 0.5, g: 0.5, b: 0.5, a: 0.4} m_Pivot: {x: 0, y: 0, z: 0} m_Size: {x: 0, y: 0} yGrid: @@ -1007,7 +996,7 @@ MonoBehaviour: m_Target: 1 speed: 2 m_Value: 1 - m_Color: {r: 0, g: 1, b: 0, a: 0.4} + m_Color: {r: 0.5, g: 0.5, b: 0.5, a: 0.4} m_Pivot: {x: 0, y: 0, z: 0} m_Size: {x: 1, y: 1} zGrid: @@ -1015,9 +1004,9 @@ MonoBehaviour: m_Target: 0 speed: 2 m_Value: 0 - m_Color: {r: 0, g: 1, b: 0, a: 0.4} + m_Color: {r: 0.5, g: 0.5, b: 0.5, a: 0.4} m_Pivot: {x: 0, y: 0, z: 0} - m_Size: {x: 1, y: 1} + m_Size: {x: 0, y: 0} m_ShowGrid: 1 m_GridAxis: 1 m_gridOpacity: 0.5 @@ -1036,12 +1025,12 @@ MonoBehaviour: m_CameraSettings: m_Speed: 1 m_SpeedNormalized: 0.5 - m_SpeedMin: 0.01 + m_SpeedMin: 0.001 m_SpeedMax: 2 m_EasingEnabled: 1 m_EasingDuration: 0.4 m_AccelerationEnabled: 1 - m_FieldOfViewHorizontalOrVertical: 60 + m_FieldOfView: 90 m_NearClip: 0.03 m_FarClip: 10000 m_DynamicClip: 1 @@ -1049,7 +1038,7 @@ MonoBehaviour: m_LastSceneViewRotation: {x: 0, y: 0, z: 0, w: 0} m_LastSceneViewOrtho: 0 m_ReplacementShader: {fileID: 0} - m_ReplacementString: + m_ReplacementString: m_SceneVisActive: 1 m_LastLockedObject: {fileID: 0} m_ViewIsLockedToObject: 0 @@ -1063,8 +1052,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12015, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_MinSize: {x: 200, y: 200} m_MaxSize: {x: 4000, y: 4000} m_TitleContent: @@ -1078,11 +1067,8 @@ MonoBehaviour: width: 387.3333 height: 618.1111 m_ViewDataDictionary: {fileID: 0} - m_OverlayCanvas: - m_LastAppliedPresetName: Default - m_SaveData: [] - m_SerializedViewNames: [] - m_SerializedViewValues: [] + m_SerializedViewsNames: [] + m_SerializedViewsValues: [] m_PlayModeViewName: GameView m_ShowGizmos: 0 m_TargetDisplay: 0 @@ -1090,8 +1076,8 @@ MonoBehaviour: m_TargetSize: {x: 871.49994, y: 1343.5} m_TextureFilterMode: 0 m_TextureHideFlags: 61 - m_RenderIMGUI: 1 - m_EnterPlayModeBehavior: 0 + m_RenderIMGUI: 0 + m_MaximizeOnPlay: 0 m_UseMipMap: 0 m_VSyncEnabled: 0 m_Gizmos: 0 @@ -1142,7 +1128,7 @@ MonoBehaviour: m_LastWindowPixelSize: {x: 871.49994, y: 1390.75} m_ClearInEditMode: 1 m_NoCameraWarning: 1 - m_LowResolutionForAspectRatios: 00000000000000000000 + m_LowResolutionForAspectRatios: 01000000000000000000 m_XRRenderMode: 0 m_RenderTexture: {fileID: 0} --- !u!114 &26 @@ -1155,8 +1141,8 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 1 m_Script: {fileID: 12003, guid: 0000000000000000e000000000000000, type: 0} - m_Name: - m_EditorClassIdentifier: + m_Name: + m_EditorClassIdentifier: m_MinSize: {x: 100, y: 100} m_MaxSize: {x: 4000, y: 4000} m_TitleContent: @@ -1170,6 +1156,4 @@ MonoBehaviour: width: 662.44446 height: 274.33337 m_ViewDataDictionary: {fileID: 0} - m_OverlayCanvas: - m_LastAppliedPresetName: Default - m_SaveData: [] + diff --git a/UserSettings/Search.index b/UserSettings/Search.index new file mode 100644 index 0000000000000000000000000000000000000000..299c246c3aa0b3b91210b18535c74eb7d9d9df82 --- /dev/null +++ b/UserSettings/Search.index @@ -0,0 +1,13 @@ +{ + "name": "Assets", + "roots": ["Assets"], + "includes": [], + "excludes": ["Temp/", "External/"], + "options": { + "types": true, + "properties": false, + "extended": false, + "dependencies": false + }, + "baseScore": 999 +} \ No newline at end of file diff --git a/UserSettings/Search.settings b/UserSettings/Search.settings index 9e26dfeeb6e641a33dae4961196235bdb965b21b..f555d982bbf36578b1408fe1cf87ece59782a192 100644 --- a/UserSettings/Search.settings +++ b/UserSettings/Search.settings @@ -1 +1,67 @@ -{} \ No newline at end of file +trackSelection = true +fetchPreview = true +wantsMore = false +keepOpen = false +queryFolder = "Assets" +onBoardingDoNotAskAgain = true +showPackageIndexes = false +showStatusBar = false +scopes = { + "last_search.8040E7BB" = "fast" + "OpenInspectorPreview.8040E7BB" = "0" + "currentGroup.8040E7BB" = "all" +} +providers = { + adb = { + active = false + priority = 2500 + defaultAction = null + } + asset = { + active = true + priority = 25 + defaultAction = null + } + store = { + active = true + priority = 100 + defaultAction = null + } + find = { + active = true + priority = 25 + defaultAction = null + } + log = { + active = false + priority = 210 + defaultAction = null + } + packages = { + active = true + priority = 90 + defaultAction = null + } + performance = { + active = false + priority = 100 + defaultAction = null + } + scene = { + active = true + priority = 50 + defaultAction = null + } +} +recentSearches = [ +] +searchItemFavorites = [ +] +savedSearchesSortOrder = 0 +showSavedSearchPanel = false +expandedQueries = [ +] +queryBuilder = false +ignoredProperties = "id;name;classname;imagecontentshash" +helperWidgetCurrentArea = "all" +disabledIndexers = ""