/// <summary> /// Renders two buttons named "Previous" and "Next". The /// "Previous" button isn't rendered in the first window. /// If button "Previous" is pressed, PrevWindow() is called. /// If button "Next" is pressed (or acceptEnterAsNext == true /// && key enter is released), NextWindow() is called. /// </summary> /// <param name="acceptEnterAsNext">True to accept key "enter" to behave button "Next" is pressed.</param> public void PrevNextButtons(bool acceptEnterAsNext = false) { bool buttonPrevPressed = false; bool buttonNextPressed = false; bool keyEnterIsReleased = acceptEnterAsNext && Event.current != null && Event.current.isKey && Event.current.type == EventType.KeyUp && (Event.current.keyCode == KeyCode.Return || Event.current.keyCode == KeyCode.KeypadEnter); GUILayout.BeginHorizontal(); { // Disable button "Previous" if we're in the first window. EditorGUI.BeginDisabledGroup(CurrentWindow == 0); { buttonPrevPressed = GUILayout.Button(GUI.MakeLabel("Previous"), GUI.Skin.button); } EditorGUI.EndDisabledGroup(); buttonNextPressed = GUILayout.Button(GUI.MakeLabel("Next"), GUI.Skin.button); } GUILayout.EndHorizontal(); if (buttonPrevPressed) { PrevWindow(); } else if (buttonNextPressed || keyEnterIsReleased) { NextWindow(); } }
public static object DeformableTerrainShovelExcavationSettingsDrawer(object[] objects, InvokeWrapper wrapper) { var data = new ExcavationSettingsResult() { Value = wrapper.Get <DeformableTerrainShovelSettings.ExcavationSettings>(objects[0]) }; if (InspectorGUI.Foldout(EditorData.Instance.GetData(objects[0] as Object, wrapper.Member.Name), InspectorGUI.MakeLabel(wrapper.Member))) { using (InspectorGUI.IndentScope.Single) { data.Value.Enabled = InspectorGUI.Toggle(GUI.MakeLabel("Enabled"), data.Value.Enabled); data.EnabledChanged = UnityEngine.GUI.changed; UnityEngine.GUI.changed = false; data.Value.CreateDynamicMassEnabled = InspectorGUI.Toggle(GUI.MakeLabel("Create Dynamic Mass Enabled"), data.Value.CreateDynamicMassEnabled); data.CreateDynamicMassEnabledChanged = UnityEngine.GUI.changed; UnityEngine.GUI.changed = false; data.Value.ForceFeedbackEnabled = InspectorGUI.Toggle(GUI.MakeLabel("Force Feedback Enabled"), data.Value.ForceFeedbackEnabled); data.ForceFeedbackEnabledChanged = UnityEngine.GUI.changed; UnityEngine.GUI.changed = false; } UnityEngine.GUI.changed = data.ContainsChanges; } return(data); }
private Tuple <PropertyWrapper, CableProperties.Direction, object> OnPropertyGUI(CableProperties.Direction dir, CableProperties properties) { Tuple <PropertyWrapper, CableProperties.Direction, object> changed = null; var data = EditorData.Instance.GetData(properties, "CableProperty" + dir.ToString()); if (InspectorGUI.Foldout(data, GUI.MakeLabel(dir.ToString()))) { using (InspectorGUI.IndentScope.Single) { var wrappers = PropertyWrapper.FindProperties <CableProperty>(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public); foreach (var wrapper in wrappers) { if (wrapper.GetContainingType() == typeof(float) && InspectorEditor.ShouldBeShownInInspector(wrapper.Member)) { var value = EditorGUILayout.FloatField(InspectorGUI.MakeLabel(wrapper.Member), wrapper.Get <float>(properties[dir])); if (UnityEngine.GUI.changed) { changed = new Tuple <PropertyWrapper, CableProperties.Direction, object>(wrapper, dir, value); UnityEngine.GUI.changed = false; } } } } } return(changed); }
public override void OnPostTargetMembersGUI() { var skin = InspectorEditor.Skin; var beginWinches = GetTargets <Wire, WireWinch>(wire => wire.BeginWinch).Where(winch => winch != null); var endWinches = GetTargets <Wire, WireWinch>(wire => wire.EndWinch).Where(winch => winch != null); if (beginWinches.Count() > 0) { GUILayout.Label(GUI.MakeLabel("Begin winch", true), skin.Label); using (InspectorGUI.IndentScope.Single) { if (beginWinches.Count() != NumTargets) { InspectorGUI.WarningLabel("Not all selected wires has a begin winch."); } InspectorEditor.DrawMembersGUI(beginWinches.ToArray()); } } if (endWinches.Count() > 0) { GUILayout.Label(GUI.MakeLabel("End winch", true), skin.Label); using (InspectorGUI.IndentScope.Single) { if (endWinches.Count() != NumTargets) { InspectorGUI.WarningLabel("Not all selected wires has an end winch."); } InspectorEditor.DrawMembersGUI(endWinches.ToArray()); } } }
public static void DrawUrdfPose(AGXUnity.IO.URDF.Pose pose) { EditorGUILayout.PrefixLabel(GUI.MakeLabel("Origin", true)); using (new InspectorGUI.IndentScope()) { InspectorGUI.Vector3Field(GUI.MakeLabel("Position"), pose.Xyz); InspectorGUI.Vector3Field(GUI.MakeLabel("Roll, Pitch, Yaw"), pose.Rpy, "R,P,Y"); } }
protected override void OnPreFrameGUI(CableRouteNode node) { using (InspectorGUI.IndentScope.Single) { node.Type = (Cable.NodeType)EditorGUILayout.EnumPopup(GUI.MakeLabel("Type"), node.Type, InspectorEditor.Skin.Popup); } }
public static void DrawUrdfPose(AGXUnity.IO.URDF.Pose pose) { UnityEngine.GUI.Label(EditorGUI.IndentedRect(EditorGUILayout.GetControlRect()), GUI.MakeLabel("Origin", true), InspectorEditor.Skin.Label); using (new InspectorGUI.IndentScope()) { InspectorGUI.Vector3Field(GUI.MakeLabel("Position"), pose.Xyz); InspectorGUI.Vector3Field(GUI.MakeLabel("Roll, Pitch, Yaw"), pose.Rpy, "R,P,Y"); } }
public static Constraint.ESolveType ConstraintSolveTypeGUI(Constraint.ESolveType solveType) { // Matching with disable buttons above where each button is 76. var position = EditorGUILayout.GetControlRect(GUILayout.Width(EditorGUIUtility.labelWidth + 2.0f * 76.0f)); solveType = (Constraint.ESolveType)EditorGUI.EnumPopup(position, GUI.MakeLabel("Solve Type", true), solveType, InspectorEditor.Skin.Popup); return(solveType); }
private void OnShapeConfigGUI(bool hasRadius) { using (InspectorGUI.IndentScope.Create(2)) { State.ShapeAsParent = InspectorGUI.Toggle(GUI.MakeLabel("Shape as parent"), State.ShapeAsParent); if (hasRadius) { State.ExpandRadius = InspectorGUI.Toggle(GUI.MakeLabel("Expand radius"), State.ExpandRadius); } } }
public static void ShapeMeshSourceGUI(Mesh currentSource, System.Action <Mesh> onNewMesh) { using (new GUI.EnabledBlock(UnityEngine.GUI.enabled && !EditorApplication.isPlayingOrWillChangePlaymode)) { var newSource = EditorGUILayout.ObjectField(GUI.MakeLabel("Source"), currentSource, typeof(Mesh), false) as Mesh; if (newSource != currentSource) { onNewMesh?.Invoke(newSource); } } }
private void MeshStatisticsGUI() { if (IsMultiSelect || Mesh.PrecomputedCollisionMeshes.Length == 0) { return; } EditorGUILayout.Space(); InspectorGUI.BrandSeparator(); var numCollisionMeshes = Mesh.PrecomputedCollisionMeshes.Length; var totNumVertices = Mesh.PrecomputedCollisionMeshes.Select(collisionMesh => collisionMesh.Vertices.Length).Sum(); var totNumTriangles = Mesh.PrecomputedCollisionMeshes.Select(collisionMesh => collisionMesh.Indices.Length).Sum() / 3; var meshPlural = numCollisionMeshes > 1 ? "es" : string.Empty; var summaryString = $"Summary ({numCollisionMeshes} mesh{meshPlural}, {totNumTriangles} triangles, {totNumVertices} vertices)"; if (InspectorGUI.Foldout(GetMeshStatisticsEditorData(Mesh), GUI.MakeLabel(summaryString))) { InspectorGUI.Separator(); EditorGUILayout.LabelField(GUI.MakeLabel("Number of meshes"), GUI.MakeLabel(Mesh.PrecomputedCollisionMeshes.Length.ToString(), Color.green), InspectorEditor.Skin.TextField); using (InspectorGUI.IndentScope.Single) { InspectorGUI.Separator(); for (int i = 0; i < Mesh.PrecomputedCollisionMeshes.Length; ++i) { var numVertices = Mesh.PrecomputedCollisionMeshes[i].Vertices.Length; var numTriangles = Mesh.PrecomputedCollisionMeshes[i].Indices.Length / 3; EditorGUILayout.LabelField(GUI.MakeLabel($"[{i}] Number of triangles (vertices)"), GUI.MakeLabel($"{numTriangles.ToString().Color( InspectorGUISkin.BrandColorBlue )} ({numVertices.ToString()})"), InspectorEditor.Skin.TextField); } InspectorGUI.Separator(); } var totNumTrianglesString = totNumTriangles.ToString().Color(InspectorGUISkin.BrandColorBlue); var hasReducedNumTriangles = Mesh.Options != null && (Mesh.Options.Mode != AGXUnity.Collide.CollisionMeshOptions.MeshMode.Trimesh || Mesh.Options.ReductionEnabled); if (hasReducedNumTriangles) { totNumTrianglesString += $" (originally: {Mesh.SourceObjects.Select( source => source.triangles.Length / 3 ).Sum().ToString().Color( Color.red )})"; } EditorGUILayout.LabelField(GUI.MakeLabel("Total number of triangles"), GUI.MakeLabel(totNumTrianglesString), InspectorEditor.Skin.TextField); } }
public static void DrawUrdfMaterial(AGXUnity.IO.URDF.Material material) { // Name has already been rendered. InspectorGUI.Toggle(GUI.MakeLabel("Is Reference"), material.IsReference); if (material.IsReference) { return; } var colorRect = EditorGUILayout.GetControlRect(); EditorGUI.PrefixLabel(colorRect, GUI.MakeLabel("Color")); var oldXMax = colorRect.xMax; colorRect.x += EditorGUIUtility.labelWidth; colorRect.xMax = oldXMax; EditorGUI.DrawRect(colorRect, material.Color); }
private void ShowForces(EventType eventType) { if (m_textLabelStyle == null) { m_textLabelStyle = new GUIStyle(GUI.Skin.label); m_textLabelStyle.alignment = TextAnchor.MiddleLeft; var fonts = Font.GetOSInstalledFontNames(); foreach (var font in fonts) { if (font == "Consolas") { m_textLabelStyle.font = Font.CreateDynamicFontFromOSFont(font, 24); break; } } } var textColor = Color.Lerp(Color.black, Color.white, 1.0f); var valueColor = Color.Lerp(Color.green, Color.white, 0.45f); Func <string, agx.Vec3, GUIContent> Vec3Content = (name, v) => { return(GUI.MakeLabel(string.Format("{0} [{1}, {2}, {3}] kN", GUI.AddColorTag(name, textColor), GUI.AddColorTag(v.x.ToString("0.00").PadLeft(7, ' '), valueColor), GUI.AddColorTag(v.y.ToString("0.00").PadLeft(7, ' '), valueColor), GUI.AddColorTag(v.z.ToString("0.00").PadLeft(7, ' '), valueColor)))); }; var shovel = m_shovels[0].Native; var penetrationForce = new agx.Vec3(); var penetrationTorque = new agx.Vec3(); Native.getPenetrationForce(shovel, ref penetrationForce, ref penetrationTorque); var separationForce = -Native.getSeparationContactForce(shovel); var deformerForce = -Native.getDeformationContactForce(shovel); var contactForce = -Native.getContactForce(shovel); GUILayout.Label(Vec3Content("Penetration force:", 1.0E-3 * penetrationForce), m_textLabelStyle); GUILayout.Space(4); GUILayout.Label(Vec3Content("Separation force: ", 1.0E-3 * separationForce), m_textLabelStyle); GUILayout.Space(4); GUILayout.Label(Vec3Content("Deformer force: ", 1.0E-3 * deformerForce), m_textLabelStyle); GUILayout.Space(4); GUILayout.Label(Vec3Content("Contact force: ", 1.0E-3 * contactForce), m_textLabelStyle); }
public static Constraint.ECollisionsState ConstraintCollisionsStateGUI(Constraint.ECollisionsState state) { var skin = InspectorEditor.Skin; var guiWasEnabled = UnityEngine.GUI.enabled; GUILayout.BeginHorizontal(); { EditorGUILayout.PrefixLabel(GUI.MakeLabel("Disable Collisions", true), InspectorEditor.Skin.LabelMiddleLeft); UnityEngine.GUI.enabled = !EditorApplication.isPlaying; var rbVsRbActive = !EditorGUI.showMixedValue && state == Constraint.ECollisionsState.DisableRigidBody1VsRigidBody2; var refVsConActive = !EditorGUI.showMixedValue && state == Constraint.ECollisionsState.DisableReferenceVsConnected; if (GUILayout.Button(GUI.MakeLabel("Rb " + GUI.Symbols.ArrowLeftRight.ToString() + " Rb", rbVsRbActive, "Disable all shapes in rigid body 1 against all shapes in rigid body 2."), skin.GetButton(rbVsRbActive, InspectorGUISkin.ButtonType.Left), GUILayout.Width(76))) { state = state == Constraint.ECollisionsState.DisableRigidBody1VsRigidBody2 ? Constraint.ECollisionsState.KeepExternalState : Constraint.ECollisionsState.DisableRigidBody1VsRigidBody2; } if (GUILayout.Button(GUI.MakeLabel("Ref " + GUI.Symbols.ArrowLeftRight.ToString() + " Con", refVsConActive, "Disable Reference object vs. Connected object."), skin.GetButton(refVsConActive, InspectorGUISkin.ButtonType.Right), GUILayout.Width(76))) { state = state == Constraint.ECollisionsState.DisableReferenceVsConnected ? Constraint.ECollisionsState.KeepExternalState : Constraint.ECollisionsState.DisableReferenceVsConnected; } UnityEngine.GUI.enabled = guiWasEnabled; } GUILayout.EndHorizontal(); return(state); }
/// <returns>True when button is pressed.</returns> private bool OnButtonGUI(Rect rect, string name, InspectorGUISkin.ButtonType buttonType, Event current, Action onMouseOver) { using (InspectorGUI.IndentScope.Create(2)) { var down = UnityEngine.GUI.Button(rect, GUI.MakeLabel(name), InspectorEditor.Skin.GetButton(true, buttonType)); if (current.type == EventType.Repaint && rect.Contains(current.mousePosition)) { onMouseOver(); } return(down); } }
public void Update(InvokeWrapper wrapper, object targetInstance) { var foldoutBeginAttribute = wrapper.GetAttribute <InspectorGroupBeginAttribute>(); if (foldoutBeginAttribute != null || wrapper.HasAttribute <InspectorGroupEndAttribute>()) { End(); } if (foldoutBeginAttribute == null) { return; } var groupIdentifier = (targetInstance != null ? targetInstance.GetType().FullName : "null") + "_" + foldoutBeginAttribute.Name; Begin(!InspectorGUI.Foldout(EditorData.Instance.GetData(targetInstance as Object, groupIdentifier), GUI.MakeLabel(foldoutBeginAttribute.Name))); }
private static void PostBuildInternal(string agxDynamicsPath, string agxPluginPath, FileInfo targetExecutableFileInfo, string targetDataPath) { // Some versions of Unity 2019.3 (fixed in 2019.3.9) isn't consistent // where native modules are located. E.g., if Burst is installed, some // dll's will be created in <project>_Data/Plugins/x86_64 and if AGX // dll's are in <project>_Data/Plugins, the dll's wont load. // - Unity 2019.3 and later: <project>_Data/Plugins/x86_64 // - Unity 2019.2 and earlier: <project>_Data/Plugins if (!Directory.Exists(AGXUnity.IO.Environment.GetPlayerPluginPath(targetDataPath))) { Directory.CreateDirectory(AGXUnity.IO.Environment.GetPlayerPluginPath(targetDataPath)); } // Assuming all dlls are present in the plugins directory and that // "Components" are in a folder named "agx" in the plugins directory. // Unity will copy the dlls. var sourceDirectory = new DirectoryInfo(IO.Utils.AGXUnityPluginDirectoryFull + Path.DirectorySeparatorChar + "agx"); var destinationDirectory = new DirectoryInfo(AGXUnity.IO.Environment.GetPlayerAGXRuntimePath(targetDataPath)); Debug.Log(GUI.AddColorTag("Copying AGX runtime data from: " + IO.Utils.AGXUnityPluginDirectory + Path.DirectorySeparatorChar + "agx" + " to " + destinationDirectory.FullName, Color.green)); CopyDirectory(sourceDirectory, destinationDirectory); // Deleting all .meta-files that are present in our "agx" folder. foreach (var fi in destinationDirectory.EnumerateFiles("*.meta", SearchOption.AllDirectories)) { fi.Delete(); } VerifyBuild(targetDataPath); CheckGenerateEncryptedRuntime(targetExecutableFileInfo); }
private static void PostBuildExternal(string agxDynamicsPath, string agxPluginPath, FileInfo targetExecutableFileInfo, string targetDataPath) { // Finding loaded modules/binaries in current process located // in current environment AGX Dynamics directory. Additional // modules/binaries that are optional, i.e., possibly located // in another directory, are also included here. var loadedAgxModulesPaths = new List <string>(); using (new DynamicallyLoadedDependencies()) { var process = Process.GetCurrentProcess(); foreach (ProcessModule module in process.Modules) { if (module.FileName.IndexOf("[In Memory]") >= 0) { continue; } var isMatch = module.FileName.IndexOf(agxDynamicsPath) == 0 || IsOutOfInstallDependency(module.FileName); if (isMatch) { loadedAgxModulesPaths.Add(module.FileName); } } } // Finding additional modules/binaries which an AGX Dynamics // runtime may depend on, e.g., vcruntimeIII.dll and msvcpIII.dll. var agxDepDir = AGXUnity.IO.Environment.Get(AGXUnity.IO.Environment.Variable.AGX_DEPENDENCIES_DIR); if (!string.IsNullOrEmpty(agxDepDir)) { var agxDepDirInfo = new DirectoryInfo(agxDepDir); foreach (var file in agxDepDirInfo.EnumerateFiles("*.dll", SearchOption.AllDirectories)) { foreach (var dependency in m_additionalDependencies) { if (System.Text.RegularExpressions.Regex.IsMatch(file.Name, dependency)) { loadedAgxModulesPaths.Add(file.FullName); } } } } if (loadedAgxModulesPaths.Count == 0) { Debug.LogWarning(GUI.AddColorTag("Copy AGX Dynamics binaries - no binaries found in current process.", Color.red)); return; } // dllTargetPath: ./<name>_Data/Plugins var dllTargetPath = AGXUnity.IO.Environment.GetPlayerPluginPath(targetDataPath); if (!Directory.Exists(dllTargetPath)) { Directory.CreateDirectory(dllTargetPath); } // agxRuntimeDataPath: ./<name>_Data/Plugins/agx var agxRuntimeDataPath = AGXUnity.IO.Environment.GetPlayerAGXRuntimePath(targetDataPath); if (!Directory.Exists(agxRuntimeDataPath)) { Directory.CreateDirectory(agxRuntimeDataPath); } Debug.Log("Copying Components to: " + GUI.AddColorTag(agxRuntimeDataPath + Path.DirectorySeparatorChar + "Components", Color.green)); CopyDirectory(new DirectoryInfo(agxPluginPath + Path.DirectorySeparatorChar + "Components"), new DirectoryInfo(agxRuntimeDataPath + Path.DirectorySeparatorChar + "Components")); var targetDataDir = agxRuntimeDataPath + Path.DirectorySeparatorChar + "data"; Debug.Log("Copying data to: " + GUI.AddColorTag(targetDataDir, Color.green)); if (!Directory.Exists(targetDataDir)) { Directory.CreateDirectory(targetDataDir); } CopyDirectory(new DirectoryInfo(agxDynamicsPath + Path.DirectorySeparatorChar + "data" + Path.DirectorySeparatorChar + "TerrainMaterials"), new DirectoryInfo(targetDataDir + Path.DirectorySeparatorChar + "TerrainMaterials")); foreach (var modulePath in loadedAgxModulesPaths) { var moduleFileInfo = new FileInfo(modulePath); try { moduleFileInfo.CopyTo(dllTargetPath + Path.DirectorySeparatorChar + moduleFileInfo.Name, true); string additionalInfo = ""; if (IsOutOfInstallDependency(modulePath)) { additionalInfo = GUI.AddColorTag($" ({modulePath})", Color.yellow); } Debug.Log("Successfully copied: " + GUI.AddColorTag(dllTargetPath + Path.DirectorySeparatorChar, Color.green) + GUI.AddColorTag(moduleFileInfo.Name, Color.Lerp(Color.blue, Color.white, 0.75f)) + additionalInfo); } catch (Exception e) { Debug.Log("Failed copying: " + GUI.AddColorTag(dllTargetPath + Path.DirectorySeparatorChar, Color.red) + GUI.AddColorTag(moduleFileInfo.Name, Color.red) + ": " + e.Message); } } CheckGenerateEncryptedRuntime(targetExecutableFileInfo); }
private static void OnPostProcessBuild(BuildTarget target, string targetPathFilename) { if (!EditorSettings.Instance.BuildPlayer_CopyBinaries) { return; } if (target != BuildTarget.StandaloneWindows64 && target != BuildTarget.StandaloneWindows) { Debug.LogWarning(GUI.AddColorTag("Copy AGX Dynamics binaries - unsupported build target: ", Color.red) + target.ToString()); return; } var nativeIsX64 = agx.agxSWIG.isBuiltWith(agx.BuildConfiguration.USE_64BIT_ARCHITECTURE); if ((target == BuildTarget.StandaloneWindows64) != nativeIsX64) { Debug.LogWarning(GUI.AddColorTag("Copy AGX Dynamics binaries - x86/x64 architecture mismatch: ", Color.red) + "Build target = " + target.ToString() + ", AGX Dynamics build: " + (nativeIsX64 ? "x64" : "x86")); return; } var agxDynamicsPath = AGXUnity.IO.Environment.AGXDynamicsPath; if (string.IsNullOrEmpty(agxDynamicsPath)) { Debug.LogWarning(GUI.AddColorTag("Copy AGX Dynamics binaries - unable to find AGX Dynamics directory.", Color.red)); return; } var agxPluginPath = AGXUnity.IO.Environment.Get(AGXUnity.IO.Environment.Variable.AGX_PLUGIN_PATH); if (string.IsNullOrEmpty(agxPluginPath)) { Debug.LogWarning(GUI.AddColorTag("Copy AGX Dynamics binaries - unable to find AGX_PLUGIN_PATH.", Color.red)); return; } var targetExecutableFileInfo = new FileInfo(targetPathFilename); if (!targetExecutableFileInfo.Exists) { Debug.LogWarning(GUI.AddColorTag("Target executable doesn't exist: ", Color.red) + targetPathFilename); return; } // Application.dataPath is 'Assets' folder here in Editor but // Application.dataPath is '<name>_Data' in the Player. We're // explicitly constructing '<name>_Data' here. var targetDataPath = targetExecutableFileInfo.Directory.FullName + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(targetExecutableFileInfo.Name) + "_Data"; if (IO.Utils.AGXDynamicsInstalledInProject) { PostBuildInternal(agxDynamicsPath, agxPluginPath, targetExecutableFileInfo, targetDataPath); } else { PostBuildExternal(agxDynamicsPath, agxPluginPath, targetExecutableFileInfo, targetDataPath); } }
public static object GenericListDrawer(object[] objects, InvokeWrapper wrapper) { var list = wrapper.Get <System.Collections.IList>(objects[0]); var target = objects[0] as Object; if (InspectorGUI.Foldout(EditorData.Instance.GetData(target, wrapper.Member.Name), InspectorGUI.MakeLabel(wrapper.Member))) { object insertElementBefore = null; object insertElementAfter = null; object eraseElement = null; var skin = InspectorEditor.Skin; var buttonLayout = new GUILayoutOption[] { GUILayout.Width(1.0f * EditorGUIUtility.singleLineHeight), GUILayout.Height(1.0f * EditorGUIUtility.singleLineHeight) }; foreach (var listObject in list) { using (InspectorGUI.IndentScope.Single) { GUILayout.BeginHorizontal(); { InspectorGUI.Separator(1.0f, EditorGUIUtility.singleLineHeight); if (InspectorGUI.Button(MiscIcon.EntryInsertBefore, true, "Insert new element before this.", buttonLayout)) { insertElementBefore = listObject; } if (InspectorGUI.Button(MiscIcon.EntryInsertAfter, true, "Insert new element after this.", buttonLayout)) { insertElementAfter = listObject; } if (InspectorGUI.Button(MiscIcon.EntryRemove, true, "Remove this element.", buttonLayout)) { eraseElement = listObject; } } GUILayout.EndHorizontal(); InspectorEditor.DrawMembersGUI(new Object[] { target }, ignored => listObject); } } InspectorGUI.Separator(1.0f, 0.5f * EditorGUIUtility.singleLineHeight); if (list.Count == 0) { GUILayout.Label(GUI.MakeLabel("Empty", true), skin.Label); } bool addElementToList = false; GUILayout.BeginHorizontal(); { GUILayout.FlexibleSpace(); addElementToList = InspectorGUI.Button(MiscIcon.EntryInsertAfter, true, "Add new element.", buttonLayout); } GUILayout.EndHorizontal(); object newObject = null; if (addElementToList || insertElementBefore != null || insertElementAfter != null) { newObject = Activator.CreateInstance(list.GetType().GetGenericArguments()[0], new object[] { }); } if (eraseElement != null) { list.Remove(eraseElement); } else if (newObject != null) { if (addElementToList || (list.Count > 0 && insertElementAfter != null && insertElementAfter == list[list.Count - 1])) { list.Add(newObject); } else if (insertElementAfter != null) { list.Insert(list.IndexOf(insertElementAfter) + 1, newObject); } else if (insertElementBefore != null) { list.Insert(list.IndexOf(insertElementBefore), newObject); } } if (eraseElement != null || newObject != null) { EditorUtility.SetDirty(target); } } // A bit of a hack until I figure out how to handle multi-selection // of lists, if that should be possible at all. We're handling the // list from inside this drawer and by returning null the return // value isn't propagated to any targets. return(null); }
public static void DrawUrdfElement(AGXUnity.IO.URDF.Element element, int elementArrayIndex = -1) { if (element == null) { return; } var dropDownName = string.IsNullOrEmpty(element.Name) ? elementArrayIndex >= 0 ? $"{element.GetType().Name}[{elementArrayIndex}]" : element.GetType().Name : element.Name; if (!InspectorGUI.Foldout(GetEditorData(element, dropDownName), GUI.MakeLabel(InspectorGUISkin.Instance.TagTypename($"Urdf.{element.GetType().Name}") + ' ' + dropDownName))) { return; } using (InspectorGUI.IndentScope.Single) { var ignoreName = element is AGXUnity.IO.URDF.Inertial; if (!ignoreName) { var nameRect = EditorGUILayout.GetControlRect(); EditorGUI.PrefixLabel(nameRect, GUI.MakeLabel("Name"), InspectorEditor.Skin.Label); var orgXMax = nameRect.xMax; nameRect.x += EditorGUIUtility.labelWidth - 14.0f * InspectorGUI.IndentScope.Level; nameRect.xMax = orgXMax; EditorGUI.SelectableLabel(nameRect, element.Name, InspectorEditor.Skin.TextField); } if (element is AGXUnity.IO.URDF.Pose) { DrawUrdfPose(element as AGXUnity.IO.URDF.Pose); } else if (element is AGXUnity.IO.URDF.Material) { DrawUrdfMaterial(element as AGXUnity.IO.URDF.Material); return; } var properties = GetOrFindProperties(element.GetType()); var elementArg = new object[] { element }; var geometry = element as AGXUnity.IO.URDF.Geometry; foreach (var property in properties) { // Ignoring Unity specific properties such as "name" and "hideFlags". if (!char.IsUpper(property.Member.Name[0])) { continue; } if (!InspectorEditor.ShouldBeShownInInspector(property.Member)) { continue; } var containingType = property.GetContainingType(); if (containingType.IsArray) { if (typeof(AGXUnity.IO.URDF.Element).IsAssignableFrom(containingType.GetElementType())) { var array = property.Get <System.Collections.ICollection>(element); if (!InspectorGUI.Foldout(GetEditorData(element, property.Member.Name), InspectorGUI.MakeLabel(property.Member, $" [{array.Count}]"))) { continue; } using (InspectorGUI.IndentScope.Single) { var arrayIndex = 0; foreach (var arrayItem in array) { DrawUrdfElement(arrayItem as AGXUnity.IO.URDF.Element, arrayIndex++); } } } } else if (typeof(AGXUnity.IO.URDF.Element).IsAssignableFrom(containingType)) { DrawUrdfElement(property.Get <AGXUnity.IO.URDF.Element>(element), -1); } else if (geometry == null || IsValidGeometryProperty(geometry, property)) { var drawerMethod = GetDrawerMethod(containingType); drawerMethod.Drawer?.Invoke(null, new object[] { elementArg, property }); } } } }
private static DefaultAndUserValueResult HandleDefaultAndUserValue <ValueT>(object[] objects, InvokeWrapper wrapper) where ValueT : struct { if (s_floatFieldMethod == null) { s_floatFieldMethod = typeof(EditorGUI).GetMethod("FloatField", new[] { typeof(Rect), typeof(string), typeof(float) }); } if (s_vector3FieldMethod == null) { s_vector3FieldMethod = typeof(EditorGUI).GetMethod("Vector3Field", new[] { typeof(Rect), typeof(string), typeof(Vector3) }); } var method = typeof(ValueT) == typeof(float) ? s_floatFieldMethod : typeof(ValueT) == typeof(Vector3) ? s_vector3FieldMethod : null; if (method == null) { throw new NullReferenceException("Unknown DefaultAndUserValue type: " + typeof(ValueT).Name); } var updateButtonWidth = 20.0f; var rect = EditorGUILayout.GetControlRect(); // Now we know the total width if the Inspector. Remove // width of button and right most spacing. rect.xMax -= updateButtonWidth; // We don't want the tooltip of the toggle to show when // hovering the update button or float field(s) so use // xMax as label width minus some magic number so that // e.g., Mass float field slider appears and works. var widthUntilButton = rect.xMax; rect.xMax = EditorGUIUtility.labelWidth - 28; // Result and reference instance. var result = new DefaultAndUserValueResult(); var instance = wrapper.Get <DefaultAndUserValue <ValueT> >(objects[0]); UnityEngine.GUI.changed = false; var hasMixedUseDefault = !CompareMulti <ValueT>(objects, wrapper, other => other.UseDefault == instance.UseDefault); EditorGUI.showMixedValue = hasMixedUseDefault; var toggleInput = hasMixedUseDefault ? false : instance.UseDefault; // During showMixedValue - Toggle will always return true (enabled) // when the user clicks regardless of instance.UseDefault. var toggleOutput = EditorGUI.ToggleLeft(rect, GUI.MakeLabel(wrapper.Member.Name.SplitCamelCase(), false, "If checked - value will be default. Uncheck to manually enter value."), toggleInput); if (toggleOutput != toggleInput) { result.DefaultToggleChanged = true; result.UseDefault = toggleOutput; } // Restore width and calculate new start of the float // field(s). Start is label width but we have to remove // the current indent level since label width is independent // of the indent level. Unsure why we have to add LayoutMagicNumber pixels... // could be float field(s) default minimum label size. rect.xMax = widthUntilButton; rect.x = EditorGUIUtility.labelWidth - InspectorGUI.IndentScope.PixelLevel + InspectorGUI.LayoutMagicNumber; rect.xMax += -rect.x + InspectorGUI.LayoutMagicNumber; s_fieldMethodArgs[0] = rect; s_fieldMethodArgs[2] = instance.Value; var newValue = default(ValueT); EditorGUI.showMixedValue = !CompareMulti <ValueT>(objects, wrapper, other => instance.Value.Equals(other.Value)); using (new GUI.EnabledBlock(!instance.UseDefault && !hasMixedUseDefault)) { EditorGUI.BeginChangeCheck(); newValue = (ValueT)method.Invoke(null, s_fieldMethodArgs); if (EditorGUI.EndChangeCheck()) { // Validate input here so that, e.g., 0 isn't propagated. It's // not possible to check this in the CopyOp callback. var clampAttribute = wrapper.GetAttribute <ClampAboveZeroInInspector>(); if (clampAttribute == null || clampAttribute.IsValid(newValue)) { result.OnChange <ValueT>(instance.Value, newValue); } } } rect.x = rect.xMax; rect.width = updateButtonWidth; rect.height = EditorGUIUtility.singleLineHeight - EditorGUIUtility.standardVerticalSpacing; result.UpdateDefaultClicked = InspectorGUI.Button(rect, MiscIcon.Update, instance.UseDefault, InspectorEditor.Skin.ButtonRight, "Force update of default value.", 1.2f); return(result); }
public override void OnPreTargetMembersGUI() { // TODO: Improvements. // - "Copy-paste" shape. // 1. Select object with primitive shape(s) // 2. Select object to copy the shape(s) to // - Move from-to existing bodies or create a new body. // - Mesh object operations. // * Simplify assembly // * Multi-select to create meshes // - Inspect element (hold 'i'). if (!AGXUnity.Utils.Math.IsUniform(Assembly.transform.lossyScale, 1.0E-3f)) { Debug.LogWarning("Scale of AGXUnity.Assembly transform isn't uniform. If a child rigid body is moving under this transform the (visual) behavior is undefined.", Assembly); } var skin = InspectorEditor.Skin; if (!IsMultiSelect) { bool rbButtonPressed = false; bool shapeButtonPressed = false; bool constraintButtonPressed = false; InspectorGUI.ToolButtons(InspectorGUI.ToolButtonData.Create(ToolIcon.CreateRigidBody, m_mode == Mode.RigidBody, "Create/manage rigid bodies in this assembly.", () => rbButtonPressed = true), InspectorGUI.ToolButtonData.Create(ToolIcon.CreateShapeGivenVisual, m_mode == Mode.Shape, "Create shapes given visual representations.", () => shapeButtonPressed = true), InspectorGUI.ToolButtonData.Create(ToolIcon.CreateConstraint, m_mode == Mode.Constraint, "Create new constraint.", () => constraintButtonPressed = true)); HandleModeGUI(); if (rbButtonPressed) { ChangeMode(Mode.RigidBody); } if (shapeButtonPressed) { ChangeMode(Mode.Shape); } if (constraintButtonPressed) { ChangeMode(Mode.Constraint); } } else { GUILayout.Label(GUI.MakeLabel("Assemblies", 24, true), skin.LabelMiddleCenter); } OnObjectListsGUI(this); }
public sealed override void OnInspectorGUI() { if (Utils.KeyHandler.HandleDetectKeyOnGUI(this.targets, Event.current)) { return; } if (IsMainEditor && !typeof(ScriptableObject).IsAssignableFrom(target.GetType())) { var controlRect = EditorGUILayout.GetControlRect(false, 0.0f); if (m_icon == null) { m_icon = IconManager.GetIcon("algoryx_white_shadow_icon"); } if (m_icon != null) { if (m_hideTexture == null) { #if UNITY_2019_3_OR_NEWER var hideColor = Color.Lerp(InspectorGUI.BackgroundColor, Color.white, 0.03f); #else var hideColor = InspectorGUI.BackgroundColor; #endif m_hideTexture = GUI.CreateColoredTexture(1, 1, hideColor); } var hideRect = new Rect(controlRect.x, #if UNITY_2019_3_OR_NEWER controlRect.y - 1.25f * EditorGUIUtility.singleLineHeight - 2, #else controlRect.y - 1.00f * EditorGUIUtility.singleLineHeight - 1, #endif 18, EditorGUIUtility.singleLineHeight + 2); UnityEngine.GUI.DrawTexture(hideRect, m_hideTexture); var iconRect = new Rect(hideRect); iconRect.height = 14.0f; iconRect.width = 14.0f; #if UNITY_2019_3_OR_NEWER iconRect.y += 2.5f; #else iconRect.y += 1.5f; #endif iconRect.x += 3.0f; UnityEngine.GUI.DrawTexture(iconRect, m_icon); } InspectorGUI.BrandSeparator(); } GUILayout.BeginVertical(); ToolManager.OnPreTargetMembers(this.targets); DrawMembersGUI(this.targets, null, serializedObject); ToolManager.OnPostTargetMembers(this.targets); GUILayout.EndVertical(); }
private void OnGUI() { ValidateLicenseDirectory(); using (GUI.AlignBlock.Center) GUILayout.Box(IconManager.GetAGXUnityLogo(), GUI.Skin.customStyles[3], GUILayout.Width(System.Math.Min(400.0f, position.width - 20.0f)), GUILayout.Height(100)); EditorGUILayout.LabelField("© " + System.DateTime.Now.Year + " Algoryx Simulation AB", InspectorEditor.Skin.LabelMiddleCenter); InspectorGUI.BrandSeparator(1, 6); m_scroll = EditorGUILayout.BeginScrollView(m_scroll); if (IsUpdatingLicenseInformation) { ShowNotification(GUI.MakeLabel("Reading...")); } else if (AGXUnity.LicenseManager.IsBusy) { ShowNotification(GUI.MakeLabel(AGXUnity.LicenseManager.IsActivating ? "Activating..." : "Refreshing...")); } using (new GUI.EnabledBlock(!IsUpdatingLicenseInformation && !AGXUnity.LicenseManager.IsBusy)) { for (int i = 0; i < m_licenseData.Count; ++i) { var data = m_licenseData[i]; LicenseDataGUI(data); if (i + 1 < m_licenseData.Count) { InspectorGUI.Separator(2, 6, InspectorGUISkin.BrandColorBlue); } } if (m_licenseData.Count > 0) { InspectorGUI.Separator(2, 6, InspectorGUISkin.BrandColorBlue); } ActivateLicenseGUI(); } InspectorGUI.BrandSeparator(1, 6); GUILayout.Label(GUI.MakeLabel("Online Documentation", true), InspectorEditor.Skin.Label); if (InspectorGUI.Link(GUI.MakeLabel("License Manager", false, s_licenseManagerUrl))) { Application.OpenURL(s_licenseManagerUrl); } if (InspectorGUI.Link(GUI.MakeLabel("Licensing AGX Dynamics for Unity", false, s_licensingUrl))) { Application.OpenURL(s_licensingUrl); } if (InspectorGUI.Link(GUI.MakeLabel("Free Trial", false, s_freeTrialUrl))) { Application.OpenURL(s_freeTrialUrl); } EditorGUILayout.EndScrollView(); if (AGXUnity.LicenseManager.IsBusy || IsUpdatingLicenseInformation) { Repaint(); } }
private void LicenseDataGUI(LicenseData data) { var highlight = m_licenseData.Count > 1 && !IsUpdatingLicenseInformation && !AGXUnity.LicenseManager.IsBusy && data.LicenseInfo.UniqueId == AGXUnity.LicenseManager.LicenseInfo.UniqueId; if (highlight && m_activeLicenseStyle == null) { m_activeLicenseStyle = new GUIStyle(InspectorEditor.Skin.Label); } // The texture is deleted when hitting stop in the editor while // m_activeLicenseStyle != null. if (m_activeLicenseStyle != null && m_activeLicenseStyle.normal.background == null) { m_activeLicenseStyle.normal.background = GUI.CreateColoredTexture(1, 1, Color.Lerp(InspectorGUI.BackgroundColor, Color.green, 0.025f)); } var licenseFileButtons = new InspectorGUI.MiscButtonData[] { InspectorGUI.MiscButtonData.Create(MiscIcon.Update, () => { RefreshLicense(data); }, UnityEngine.GUI.enabled && data.LicenseInfo.Type == AGXUnity.LicenseInfo.LicenseType.Service, "Refresh license from server."), InspectorGUI.MiscButtonData.Create(MiscIcon.EntryRemove, () => { var deactivateDelete = EditorUtility.DisplayDialog("Deactivate and erase license.", "Would you like to deactivate the current license " + "and remove the license file from this project?\n\n" + "It's possible to activate the license again in this " + "License Manager and/or download the license file again " + "from the license portal.", "Yes", "Cancel"); if (deactivateDelete) { AGXUnity.LicenseManager.DeactivateAndDelete(data.Filename); StartUpdateLicenseInformation(); } }, UnityEngine.GUI.enabled, "Deactivate and erase license file from project.") }; var highlightScope = highlight ? new EditorGUILayout.VerticalScope(m_activeLicenseStyle) : null; InspectorGUI.SelectableTextField(GUI.MakeLabel("License file"), data.Filename, licenseFileButtons); InspectorGUI.SelectableTextField(GUI.MakeLabel("License type"), data.LicenseInfo.TypeDescription); InspectorGUI.Separator(1, 6); InspectorGUI.LicenseEndDateField(data.LicenseInfo); EditorGUILayout.EnumFlagsField(GUI.MakeLabel("Enabled modules", false, data.LicenseInfo.EnabledModules.ToString()), data.LicenseInfo.AllModulesEnabled ? AGXUnity.LicenseInfo.Module.All : data.LicenseInfo.EnabledModules, false, InspectorEditor.Skin.Popup); InspectorGUI.SelectableTextField(GUI.MakeLabel("User"), data.LicenseInfo.User); InspectorGUI.SelectableTextField(GUI.MakeLabel("Contact"), data.LicenseInfo.Contact); highlightScope?.Dispose(); }
private void HandleModeRigidBodyGUI() { var skin = InspectorEditor.Skin; using (GUI.AlignBlock.Center) { if (m_subMode == SubMode.SelectRigidBody) { GUILayout.Label(GUI.MakeLabel("Select rigid body object in scene view.", true), skin.Label); } else { GUILayout.Label(GUI.MakeLabel("Select object(s) in scene view.", true), skin.Label); } } bool selectionHasRigidBody = m_selection.Find(entry => entry.Object.GetComponentInParent <RigidBody>() != null) != null; bool createNewRigidBodyPressed = false; bool addToExistingRigidBodyPressed = false; bool moveToNewRigidBodyPressed = false; GUILayout.BeginHorizontal(); { GUILayout.Space(12); GUILayout.BeginVertical(); { UnityEngine.GUI.enabled = m_selection.Count == 0 || !selectionHasRigidBody; createNewRigidBodyPressed = GUILayout.Button(GUI.MakeLabel("Create new" + (m_selection.Count == 0 ? " (empty)" : ""), false, "Create new rigid body with selected objects"), skin.Button, GUILayout.Width(128)); UnityEngine.GUI.enabled = m_selection.Count > 0 && Assembly.GetComponentInChildren <RigidBody>() != null; addToExistingRigidBodyPressed = GUILayout.Button(GUI.MakeLabel("Add to existing", false, "Add selected objects to existing rigid body"), skin.GetButton(m_subMode == SubMode.SelectRigidBody), GUILayout.Width(100)); UnityEngine.GUI.enabled = selectionHasRigidBody; moveToNewRigidBodyPressed = GUILayout.Button(GUI.MakeLabel("Move to new", false, "Move objects that already contains a rigid body to a new rigid body"), skin.Button, GUILayout.Width(85)); UnityEngine.GUI.enabled = true; } GUILayout.EndVertical(); } GUILayout.EndHorizontal(); // Creates new rigid body and move selected objects to it (as children). if (createNewRigidBodyPressed || moveToNewRigidBodyPressed) { CreateOrMoveToRigidBodyFromSelectionEntries(m_selection); m_selection.Clear(); } // Toggle to select a rigid body in scene view to move the current selection to. else if (addToExistingRigidBodyPressed) { // This will toggle if sub-mode already is SelectRigidBody. ChangeSubMode(SubMode.SelectRigidBody); } // The user has chosen a rigid body to move the current selection to. if (m_rbSelection != null) { CreateOrMoveToRigidBodyFromSelectionEntries(m_selection, m_rbSelection.RigidBody.gameObject); m_selection.Clear(); ChangeSubMode(SubMode.None); } }
public void OnInspectorGUI() { InspectorGUI.OnDropdownToolBegin($"Disable collisions between {m_mainObject.name} and other objects selected in Scene View."); var skin = InspectorEditor.Skin; var emptyContent = GUI.MakeLabel(" "); EditorGUILayout.LabelField(GUI.MakeLabel("Disable: ", true), SelectGameObjectDropdownMenuTool.GetGUIContent(m_mainObject), skin.TextArea); EditorGUILayout.LabelField(emptyContent, GUI.MakeLabel(GUI.Symbols.ArrowLeftRight.ToString())); if (m_selected.Count == 0) { EditorGUILayout.LabelField(emptyContent, GUI.MakeLabel("Select object(s) in scene view" + AwaitingUserActionDots()), skin.TextArea); } else { int removeIndex = -1; for (int i = 0; i < m_selected.Count; ++i) { GUILayout.BeginHorizontal(); { EditorGUILayout.LabelField(emptyContent, SelectGameObjectDropdownMenuTool.GetGUIContent(m_selected[i]), skin.TextArea); if (InspectorGUI.Button(MiscIcon.EntryRemove, true, "Remove pair.", GUILayout.Width(14))) { removeIndex = i; } } GUILayout.EndHorizontal(); } if (removeIndex >= 0) { m_selected.RemoveAt(removeIndex); } } var applyCancelState = InspectorGUI.PositiveNegativeButtons(m_selected.Count > 0, "Apply", "Apply current configuration.", "Cancel"); if (applyCancelState == InspectorGUI.PositiveNegativeResult.Positive) { string selectedGroupName = m_mainObject.GetInstanceID().ToString(); string mainObjectGroupName = ""; for (int i = 0; i < m_selected.Count; ++i) { mainObjectGroupName += m_selected[i].GetInstanceID().ToString() + (i != m_selected.Count - 1 ? "_" : ""); } Undo.SetCurrentGroupName("Disabling collisions"); var undoGroupId = Undo.GetCurrentGroup(); if (m_mainObject.GetComponent <CollisionGroups>() == null) { Undo.AddComponent <CollisionGroups>(m_mainObject); } Undo.RecordObject(m_mainObject.GetComponent <CollisionGroups>(), "Adding collision group"); m_mainObject.GetComponent <CollisionGroups>().AddGroup(mainObjectGroupName, ShouldPropagateToChildren(m_mainObject)); foreach (var selected in m_selected) { if (selected.GetComponent <CollisionGroups>() == null) { Undo.AddComponent <CollisionGroups>(selected); } Undo.RecordObject(selected.GetComponent <CollisionGroups>(), "Adding collision group"); selected.GetComponent <CollisionGroups>().AddGroup(selectedGroupName, ShouldPropagateToChildren(selected)); } // TopMenu.GetOrCreate works with Undo. Undo.RecordObject(TopMenu.GetOrCreateUniqueGameObject <CollisionGroupsManager>(), "Adding collision group to manager."); CollisionGroupsManager.Instance.SetEnablePair(mainObjectGroupName, selectedGroupName, false); Undo.CollapseUndoOperations(undoGroupId); PerformRemoveFromParent(); } else if (applyCancelState == InspectorGUI.PositiveNegativeResult.Negative) { PerformRemoveFromParent(); } InspectorGUI.OnDropdownToolEnd(); }
/// <summary> /// Read data given root/robot element in a XML document. /// </summary> /// <param name="root"></param> public override void Read(XElement root, bool optional) { // Reading mandatory 'name'. base.Read(root, false); // Reading material declarations - materials that can be referenced with name. var materials = new List <Material>(); foreach (var materialElement in root.Elements("material")) { var material = Instantiate <Material>(materialElement); // Material reference under the robot? // <material name="foo"> // <color rgba="1 0 0 1"/> // </material> // <material name="foo"/> // It's a no-op. if (material.IsReference && GetMaterial(material.name) != null) { Object.DestroyImmediate(material); continue; } if (m_materialTable.ContainsKey(material.Name)) { throw new UrdfIOException($"{Utils.GetLineInfo( materialElement )}: Non-unique material name '{material.Name}'."); } m_materialTable.Add(material.Name, materials.Count); materials.Add(material); } m_materials = materials.ToArray(); // Reading links defined under the "robot" scope. var links = new List <Link>(); var localMaterials = new HashSet <string>(); var warningBeginStr = GUI.AddColorTag("URDF Warning", Color.yellow); foreach (var linkElement in root.Elements("link")) { var link = Instantiate <Link>(linkElement); if (m_linkTable.ContainsKey(link.Name)) { throw new UrdfIOException($"{Utils.GetLineInfo( linkElement )}: Non-unique link name '{link.Name}'."); } // Render materials with unique name is added to the global // library as we instantiate the model. var newDefinedMaterials = link.Visuals.Where(visual => visual.Material != null && !visual.Material.IsReference && !localMaterials.Contains(visual.Material.Name) && GetMaterial(visual.Material.Name) == null).Select(visual => visual.Material.Name).ToArray(); foreach (var newDefinedMaterialName in newDefinedMaterials) { localMaterials.Add(newDefinedMaterialName); } var missingMaterialReferences = link.Visuals.Where(visual => visual.Material != null && visual.Material.IsReference && !localMaterials.Contains(visual.Material.Name) && GetMaterial(visual.Material.Name) == null).Select(visual => visual.Material).ToArray(); if (missingMaterialReferences.Length > 0) { Debug.LogWarning($"{warningBeginStr}: {link.Name} contains " + $"{missingMaterialReferences.Length} missing material references:"); foreach (var missingMaterialReference in missingMaterialReferences) { Debug.LogWarning($" {Utils.GetLineInfo( missingMaterialReference.LineNumber )}: <material name = \"{missingMaterialReference.Name}\"/>"); } } m_linkTable.Add(link.Name, links.Count); links.Add(link); RequiresResourceLoader = RequiresResourceLoader || FindRequiresResourceLoader(link); } m_links = links.ToArray(); // Reading joints defined under the "robot" scope. var joints = new List <UJoint>(); foreach (var jointElement in root.Elements("joint")) { var joint = Instantiate <UJoint>(jointElement); if (m_jointTable.ContainsKey(joint.Name)) { throw new UrdfIOException($"{Utils.GetLineInfo( jointElement )}: Non-unique link name '{joint.Name}'."); } if (GetLink(joint.Parent) == null) { throw new UrdfIOException($"{Utils.GetLineInfo( jointElement )}: Joint parent link with name {joint.Parent} doesn't exist."); } var childLink = GetLink(joint.Child); if (childLink == null) { throw new UrdfIOException($"{Utils.GetLineInfo( jointElement )}: Joint child link with name {joint.Child} doesn't exist."); } m_jointTable.Add(joint.Name, joints.Count); joints.Add(joint); // Avoiding warning for "world" type of links, i.e., 'parentLink' of // this joint may have inertial == null. if (childLink.Inertial == null && childLink.Collisions.Length == 0) { Debug.LogWarning($"{warningBeginStr} [{Utils.GetLineInfo( childLink.LineNumber )}]: Intermediate link '{childLink.Name}' is defined without " + $"<inertial> and <collision> which results in default mass (1) and default inertia diagonal (1, 1, 1)."); } } m_joints = joints.ToArray(); // Verifying "mimic" references in the joints. foreach (var joint in Joints) { if (joint.Mimic.Enabled && GetJoint(joint.Mimic.Joint) == null) { throw new UrdfIOException($"{Utils.GetLineInfo( joint.LineNumber )}: Mimic joint '{joint.Mimic.Joint}' isn't defined."); } } }
private void ActivateLicenseGUI() { GUILayout.Label(GUI.MakeLabel("Activate license", true), InspectorEditor.Skin.Label); var selectLicenseRect = GUILayoutUtility.GetLastRect(); selectLicenseRect.x += selectLicenseRect.width; selectLicenseRect.width = 28; selectLicenseRect.x -= selectLicenseRect.width; selectLicenseRect.y -= EditorGUIUtility.standardVerticalSpacing; var selectLicensePressed = InspectorGUI.Button(selectLicenseRect, MiscIcon.Locate, UnityEngine.GUI.enabled, "Select license file on this computer", 1.25f); if (selectLicensePressed) { var sourceLicense = EditorUtility.OpenFilePanel("Copy AGX Dynamics license file", ".", $"{AGXUnity.LicenseManager.GetLicenseExtension( AGXUnity.LicenseInfo.LicenseType.Service ).Remove( 0, 1 )}," + $"{AGXUnity.LicenseManager.GetLicenseExtension( AGXUnity.LicenseInfo.LicenseType.Legacy ).Remove( 0, 1 )}"); if (!string.IsNullOrEmpty(sourceLicense)) { var targetLicense = AGXUnity.IO.Environment.FindUniqueFilename($"{LicenseDirectory}/{Path.GetFileName( sourceLicense )}").PrettyPath(); if (EditorUtility.DisplayDialog("Copy AGX Dynamics license", $"Copy \"{sourceLicense}\" to \"{targetLicense}\"?", "Yes", "Cancel")) { try { File.Copy(sourceLicense, targetLicense, false); StartUpdateLicenseInformation(); GUIUtility.ExitGUI(); } catch (ExitGUIException) { throw; } catch (System.Exception e) { Debug.LogException(e); } } } } using (InspectorGUI.IndentScope.Single) { m_licenseActivateData.Id = EditorGUILayout.TextField(GUI.MakeLabel("License Id"), m_licenseActivateData.Id, InspectorEditor.Skin.TextField); if (m_licenseActivateData.Id.Any(c => !char.IsDigit(c))) { m_licenseActivateData.Id = new string( m_licenseActivateData.Id.Where(c => char.IsDigit(c)).ToArray()); } m_licenseActivateData.Password = EditorGUILayout.PasswordField(GUI.MakeLabel("Activation Code"), m_licenseActivateData.Password); InspectorGUI.SelectFolder(GUI.MakeLabel("License File Directory"), LicenseDirectory, "License file directory", newDirectory => { newDirectory = newDirectory.PrettyPath(); if (string.IsNullOrEmpty(newDirectory)) { newDirectory = "Assets"; } if (!Directory.Exists(newDirectory)) { Debug.LogWarning($"Invalid license directory: {newDirectory} - directory doesn't exist."); return; } else if (!IO.Utils.IsValidProjectFolder(newDirectory)) { Debug.LogWarning($"Invalid license directory: {newDirectory} - directory has to be in the project."); return; } LicenseDirectory = newDirectory; }); using (new GUI.EnabledBlock(UnityEngine.GUI.enabled && m_licenseActivateData.Id.Length > 0 && m_licenseActivateData.Password.Length > 0)) { // It isn't possible to press this button during activation. if (UnityEngine.GUI.Button(EditorGUI.IndentedRect(EditorGUILayout.GetControlRect()), GUI.MakeLabel(AGXUnity.LicenseManager.IsBusy ? "Activating..." : "Activate"), InspectorEditor.Skin.Button)) { AGXUnity.LicenseManager.ActivateAsync(System.Convert.ToInt32(m_licenseActivateData.Id), m_licenseActivateData.Password, LicenseDirectory, success => { if (success) { m_licenseActivateData = IdPassword.Empty(); } else { Debug.LogError("License Error: ".Color(Color.red) + AGXUnity.LicenseManager.LicenseInfo.Status); } StartUpdateLicenseInformation(); UnityEngine.GUI.FocusControl(""); }); } } } }