/// <summary>
        /// Creates a new tooltip with a title, a summary, and an optional array of characters for the shortcut.
        ///
        /// To specify modifier keys, use the Windows control keys. ProBuilder manages switching to Linux
        /// control keys for the macOS and Linux versions of the Unity Editor.
        /// </summary>
        /// <param name="title">The header text for this tooltip.</param>
        /// <param name="summary">The body of the tooltip text. This should be kept brief.</param>
        /// <param name="shortcut">A set of keys to be displayed as the shortcut for this action.</param>
        public TooltipContent(string title, string summary, params char[] shortcut) : this(title, summary, "")
        {
            if (shortcut != null && shortcut.Length > 0)
            {
                this.shortcut = string.Empty;

                for (int i = 0; i < shortcut.Length - 1; i++)
                {
                    if (!EditorUtility.IsUnix())
                    {
                        this.shortcut += InternalUtility.ControlKeyString(shortcut[i]) + " + ";
                    }
                    else
                    {
                        this.shortcut += shortcut[i] + " + ";
                    }
                }

                if (!EditorUtility.IsUnix())
                {
                    this.shortcut += InternalUtility.ControlKeyString(shortcut[shortcut.Length - 1]);
                }
                else
                {
                    this.shortcut += shortcut[shortcut.Length - 1];
                }
            }
        }
            /// <summary>
            /// Force a rebuild of all editor picking meshes for all graphics attached to all
            /// groups.  Editor picking meshes are what allow graphics to be accurately picked
            /// in the scene view even if they are in a curved space.
            /// </summary>
            public void RebuildEditorPickingMeshes()
            {
                //No picking meshes for prefabs
                if (InternalUtility.IsPrefab(_renderer))
                {
                    return;
                }

                if (!Application.isPlaying)
                {
                    if (_renderer._space != null)
                    {
                        _renderer._space.RebuildHierarchy();
                        _renderer._space.RecalculateTransformers();
                    }

                    validateGraphics();

                    foreach (var group in _renderer._groups)
                    {
                        group.editor.ValidateGraphicList();
                        group.RebuildFeatureData();
                        group.RebuildFeatureSupportInfo();
                        group.editor.RebuildEditorPickingMeshes();
                    }
                }

                foreach (var group in _renderer._groups)
                {
                    group.editor.RebuildEditorPickingMeshes();
                }
            }
        protected virtual void OnEnable()
        {
#if UNITY_EDITOR
            if (InternalUtility.IsPrefab(this))
            {
                return;
            }

            if (Application.isPlaying)
            {
#endif
            //If we are not attached, and if we are about not about to become attached
            if (!isAttachedToGroup && !_willBeAttached)
            {
                var parentRenderer = GetComponentInParent <LeapGraphicRenderer>();
                if (parentRenderer != null)
                {
                    parentRenderer.TryAddGraphic(this);
                }
            }

            patchReferences();
#if UNITY_EDITOR
        }
#endif
        }
        bool GeoLevelShortcuts(Shortcut shortcut)
        {
            switch (shortcut.action)
            {
            case "Escape":
                ClearElementSelection();
                EditorUtility.ShowNotification("Top Level");
                UpdateSelection();
                selectMode = SelectMode.Object;
                return(true);

            // Used to be (incorrectly) named handle pivot, and since shortcuts are serialized this value is still valid
            case "Toggle Handle Pivot":
            case "Toggle Handle Orientation":
                VertexManipulationTool.handleOrientation = InternalUtility.NextEnumValue(VertexManipulationTool.handleOrientation);
                return(true);

            // TODO Remove once a workaround for non-upper-case shortcut chars is found
            case "Toggle Selection Mode":
                if (s_UniqueModeShortcuts)
                {
                    return(false);
                }
                ToggleSelectionMode();
                EditorUtility.ShowNotification(selectMode.ToString());
                return(true);

            case "Delete Face":
                EditorUtility.ShowNotification(EditorToolbarLoader.GetInstance <DeleteFaces>().DoAction().notification);
                return(true);

            case "Set Pivot":

                if (selection.Count > 0)
                {
                    foreach (ProBuilderMesh pbo in selection)
                    {
                        UndoUtility.RecordObjects(new UObject[2] {
                            pbo, pbo.transform
                        }, "Set Pivot");

                        if (pbo.selectedIndexesInternal.Length > 0)
                        {
                            pbo.CenterPivot(pbo.selectedIndexesInternal);
                        }
                        else
                        {
                            pbo.CenterPivot(null);
                        }
                    }

                    EditorUtility.ShowNotification("Set Pivot");
                }

                return(true);

            default:
                return(false);
            }
        }
        static void UndoRedoPerformed()
        {
            // material preview when dragging in scene-view is done by applying then undoing changes. we don't want to
            // rebuild the mesh every single frame when dragging.
            if (SceneDragAndDropListener.isDragging)
            {
                return;
            }

            // Synchronize just checks that the mesh is not null, and UV2 is still valid. This should be very cheap except
            // for the FindObjectsOfType call.
            foreach (var mesh in Object.FindObjectsOfType <ProBuilderMesh>())
            {
                EditorUtility.SynchronizeWithMeshFilter(mesh);
                mesh.InvalidateCaches();
            }

            foreach (var mesh in InternalUtility.GetComponents <ProBuilderMesh>(Selection.transforms))
            {
                mesh.InvalidateCaches();
                mesh.Rebuild();
                mesh.Optimize();
            }

            ProBuilderEditor.Refresh();
            SceneView.RepaintAll();
        }
        public override ActionResult DoAction()
        {
            mode = InternalUtility.NextEnumValue(mode);

            return(new ActionResult(ActionResult.Status.Success,
                                    "Set Drag Select\n" + (mode == RectSelectMode.Complete ? "Complete" : "Intersect")));
        }
示例#7
0
 public static void RegisterListener(Action <PathfinderEvent> listener, string debugName = null, int?priority = null)
 {
     InternalUtility.ValidateNoId(log: false);
     RegisterExpressionListener(listener.Method.GetParameters()[0].ParameterType,
                                new ListenerObject(listener.Method, new ListenerOptions {
         DebugName = debugName, PriorityStore = priority
     }));
 }
示例#8
0
 /// <summary>
 /// Registers an event listener by compile time type.
 /// </summary>
 /// <param name="listener">The listener function that will be executed on an event call</param>
 /// <param name="debugName">Name to assign for debug purposes</param>
 /// <typeparam name="T">The PathfinderEvent Compile time Type to listen for</typeparam>
 public static void RegisterListener <T>(Action <T> listener, string debugName, int?priority)
     where T : PathfinderEvent
 {
     InternalUtility.ValidateNoId(log: false);
     RegisterExpressionListener(typeof(T), new ListenerObject(listener.Method,
                                                              new ListenerOptions {
         DebugName = debugName, PriorityStore = priority
     }));
 }
 public static Color GetColor(string key, Color fallback)
 {
     if (s_Preferences != null && preferences.HasKey <Color>(key))
     {
         return(preferences.GetColor(key, fallback));
     }
     InternalUtility.TryParseColor(EditorPrefs.GetString(key), ref fallback);
     return(fallback);
 }
示例#10
0
        bool HasFrameBounds()
        {
            if (m_Mesh == null)
            {
                m_Mesh = (ProBuilderMesh)target;
            }

            return(ProBuilderEditor.instance != null &&
                   InternalUtility.GetComponents <ProBuilderMesh>(Selection.transforms).Sum(x => x.selectedIndexesInternal.Length) > 0);
        }
示例#11
0
 /// <summary>
 /// Registers a daemon interface.
 /// </summary>
 /// <returns>The daemon's full id if added to the game, <c>null</c> otherwise.</returns>
 /// <param name="id">The daemon interface id to insert.</param>
 /// <param name="inter">The interface to add.</param>
 public static string RegisterDaemon(string id, Interface inter)
 {
     id = InternalUtility.Validate(id, "Daemon", inter.GetType().FullName, true);
     if (ModDaemons.ContainsKey(id))
     {
         return(null);
     }
     ModDaemons.Add(id, inter);
     return(id);
 }
            private void onAnySave()
            {
                if (_renderer == null || InternalUtility.IsPrefab(_renderer))
                {
                    InternalUtility.OnAnySave -= onAnySave;
                    return;
                }

                DoEditorUpdateLogic(fullRebuild: true);
            }
示例#13
0
            public void DoLateUpdateEditor()
            {
                Undo.RecordObject(_renderer, "Update graphic renderer.");
                Assert.IsFalse(InternalUtility.IsPrefab(_renderer), "Should never do editor updates for prefabs");

                _renderer.validateSpaceComponent();

                bool needsRebuild = false;

                using (new ProfilerSample("Calculate Should Rebuild"))
                {
                    foreach (var group in _renderer._groups)
                    {
#if UNITY_EDITOR
                        if (!Application.isPlaying)
                        {
                            group.editor.ValidateGraphicList();
                        }
#endif

                        foreach (var graphic in group.graphics)
                        {
                            if (graphic.isRepresentationDirty)
                            {
                                needsRebuild = true;
                                break;
                            }
                        }

                        foreach (var feature in group.features)
                        {
                            if (feature.isDirty)
                            {
                                needsRebuild = true;
                                break;
                            }
                        }
                    }

                    Hash hierarchyHash = Hash.GetHierarchyHash(_renderer.transform);

                    if (_renderer._space != null)
                    {
                        hierarchyHash.Add(_renderer._space.GetSettingHash());
                    }

                    if (_previousHierarchyHash != hierarchyHash)
                    {
                        _previousHierarchyHash = hierarchyHash;
                        needsRebuild           = true;
                    }
                }

                DoEditorUpdateLogic(needsRebuild);
            }
示例#14
0
 public static string RegisterPort(string id, Type port)
 {
     id = InternalUtility.Validate(id, "Port Type", $"[{port}]", true);
     if (PortTypes.ContainsKey(id))
     {
         return(null);
     }
     port.PortId = id;
     PortTypes.Add(id, port);
     return(id);
 }
示例#15
0
        private static void RegisterExpressionListener(Type pathfinderEventType, ListenerObject listenerObj)
        {
            InternalUtility.ValidateNoId("Event Listener", listenerObj.Options.DebugName, $" with priority {listenerObj.Options.Priority}");
            if (!eventListeners.ContainsKey(pathfinderEventType))
            {
                eventListeners.Add(pathfinderEventType, new List <ListenerObject>());
            }
            var list = eventListeners[pathfinderEventType];

            list.Add(listenerObj);
            list.Sort((x, y) => y.Options.Priority - x.Options.Priority);
        }
            public void DoEditorUpdateLogic(bool fullRebuild)
            {
                Undo.RecordObject(_renderer, "Do Editor Update Logic");

                Assert.IsFalse(InternalUtility.IsPrefab(_renderer), "Should never do editor updates for prefabs");

                using (new ProfilerSample("Validate Space Component")) {
                    _renderer.validateSpaceComponent();
                }

                if (fullRebuild)
                {
                    if (_renderer._space != null)
                    {
                        using (new ProfilerSample("Rebuild Space")) {
                            _renderer._space.RebuildHierarchy();
                            _renderer._space.RecalculateTransformers();
                        }
                    }

                    using (new ProfilerSample("Validate graphics")) {
                        validateGraphics();
                    }

                    foreach (var group in _renderer._groups)
                    {
                        using (new ProfilerSample("Validate Graphic List")) {
                            group.editor.ValidateGraphicList();
                        }

                        using (new ProfilerSample("Rebuild Feature Data")) {
                            group.RebuildFeatureData();
                        }

                        using (new ProfilerSample("Rebuild Feature Support Info")) {
                            group.RebuildFeatureSupportInfo();
                        }

                        using (new ProfilerSample("Update Renderer Editor")) {
                            group.editor.UpdateRendererEditor();
                        }
                    }
                }

                using (new ProfilerSample("Update Renderer")) {
                    foreach (var group in _renderer._groups)
                    {
                        group.UpdateRenderer();
                    }
                }

                Undo.CollapseUndoOperations(Undo.GetCurrentGroup());
            }
示例#17
0
 static void SetIsTrigger(bool val, GameObject target)
 {
     Collider[] colliders = InternalUtility.GetComponents <Collider>(target);
     foreach (Collider col in colliders)
     {
         if (val && col is MeshCollider)
         {
             ((MeshCollider)col).convex = true;
         }
         col.isTrigger = val;
     }
 }
示例#18
0
        private void OnValidate()
        {
#if UNITY_EDITOR
            if (!InternalUtility.IsPrefab(this))
            {
                if (!Application.isPlaying)
                {
                    editor.ScheduleRebuild();
                }
                editor.OnValidate();
            }
#endif
        }
示例#19
0
            public override ProBuilderMesh Build(bool isPreview = false)
            {
                var positions = InternalUtility.StringToVector3Array(verts);

                if (positions.Length % 4 == 0)
                {
                    return(ProBuilderMesh.CreateInstanceWithPoints(
                               InternalUtility.StringToVector3Array(verts)
                               ));
                }

                return(ProBuilderMesh.Create());
            }
        Bounds OnGetFrameBounds()
        {
            if (!ProBuilderEditor.selectMode.IsMeshElementMode())
            {
                return(m_MeshRenderer != null ? m_MeshRenderer.bounds : default(Bounds));
            }

            if (onGetFrameBoundsEvent != null)
            {
                onGetFrameBoundsEvent();
            }

            Vector3 min = Vector3.zero, max = Vector3.zero;
            bool    init = false;

            foreach (ProBuilderMesh mesh in InternalUtility.GetComponents <ProBuilderMesh>(Selection.transforms))
            {
                int[] tris = mesh.selectedIndexesInternal;

                if (tris == null || tris.Length < 1)
                {
                    continue;
                }

                Vector3[] verts = mesh.positionsInternal;
                var       trs   = mesh.transform;

                if (!init)
                {
                    init = true;
                    min  = trs.TransformPoint(verts[tris[0]]);
                    max  = trs.TransformPoint(verts[tris[0]]);
                }

                for (int i = 0, c = tris.Length; i < c; i++)
                {
                    Vector3 p = trs.TransformPoint(verts[tris[i]]);

                    min.x = Mathf.Min(p.x, min.x);
                    max.x = Mathf.Max(p.x, max.x);

                    min.y = Mathf.Min(p.y, min.y);
                    max.y = Mathf.Max(p.y, max.y);

                    min.z = Mathf.Min(p.z, min.z);
                    max.z = Mathf.Max(p.z, max.z);
                }
            }

            return(new Bounds((min + max) / 2f, max != min ? max - min : Vector3.one * .1f));
        }
示例#21
0
        /// <summary>
        /// Adds an executable interface by id.
        /// </summary>
        /// <returns>The full mod id if added to the game, <c>null</c> otherwise.</returns>
        /// <param name="id">The Executable Identifier to try and add.</param>
        /// <param name="inter">The interface object.</param>
        public static string RegisterExecutable(string id, Interface inter)
        {
            id = InternalUtility.Validate(id, "Executable Interface", inter.GetType().FullName, true);
            if (ModExecutables.ContainsKey(id))
            {
                return(null);
            }
            var type     = inter.GetType();
            var fileData = GenerateFileDataString(type.Assembly.GetName().Name, type.FullName, id);

            if (fileData.Length < 1 || ModExecutables.Any(pair => pair.Value.Item2 == fileData))
            {
                throw new ArgumentException("created data for '" + id + "' is not unique");
            }
            ModExecutables.Add(id, new Tuple <Interface, string>(inter, fileData));
            return(id);
        }
        public static void MenuRemoveDegenerateTriangles()
        {
            int count = 0;

            foreach (ProBuilderMesh pb in InternalUtility.GetComponents <ProBuilderMesh>(Selection.transforms))
            {
                int removedVertexCount;

                if (!MeshValidation.EnsureMeshIsValid(pb, out removedVertexCount))
                {
                    pb.Rebuild();
                    pb.Optimize();
                    count += removedVertexCount;
                }
            }

            EditorUtility.ShowNotification("Removed " + count + " vertices \nbelonging to degenerate triangles.");
        }
示例#23
0
        public static void MenuRemoveDegenerateTriangles()
        {
            int count = 0;

            foreach (ProBuilderMesh pb in InternalUtility.GetComponents <ProBuilderMesh>(Selection.transforms))
            {
                pb.ToMesh();

                int[] rm = pb.RemoveDegenerateTriangles();
                count += rm != null ? rm.Length : 0;

                pb.ToMesh();
                pb.Refresh();
                pb.Optimize();
            }

            EditorUtility.ShowNotification("Removed " + (count / 3) + " degenerate triangles.");
        }
示例#24
0
        private void LateUpdate()
        {
#if UNITY_EDITOR
            //No updates for prefabs!
            if (InternalUtility.IsPrefab(this))
            {
                return;
            }

            if (!Application.isPlaying)
            {
                editor.DoLateUpdateEditor();
            }
            else
#endif
            {
                doLateUpdateRuntime();
            }
        }
            public void OnValidate()
            {
                Assert.IsFalse(InternalUtility.IsPrefab(_renderer), "Should never run editor validation on a prefab");

                for (int i = _renderer._groups.Count; i-- > 0;)
                {
                    if (_renderer._groups[i] == null)
                    {
                        _renderer._groups.RemoveAt(i);
                    }
                }

                _renderer.validateSpaceComponent();

                foreach (var group in _renderer._groups)
                {
                    group.editor.OnValidate();
                }
            }
    void StubCodeAndSave(string assetPath, string allScript, string stubCode)
    {
        var ioPath    = Application.dataPath.Replace("Assets", "") + assetPath;
        var lastIndex = allScript.LastIndexOf("}");
        var text      = allScript.Substring(0, lastIndex);

        var sb = new StringBuilder();

        sb.Append(text);
        sb.AppendLine("");
        var line = sb.ToString().Split('\n').Length;

        sb.AppendLine(stubCode);
        sb.AppendLine("}");

        var script = sb.ToString();

        SaveWindowScript(assetPath, script);
        InternalUtility.OpenFileOnSpecificLineAndColumn(ioPath, line, 0);
    }
示例#27
0
        /// <summary>
        /// Older versions of probuilder stored a fixed size array of colors in EditorPrefs. Use this function to get a
        /// pb_ColorPalette from the older version.
        /// </summary>
        /// <returns>
        /// </returns>
        static void CopyColorsFromEditorPrefs(ColorPalette target)
        {
            List <Color> colors = new List <Color>();

            for (int i = 0; i < k_EditorPrefsColorPaletteCount; i++)
            {
                Color color = Color.white;

                if (InternalUtility.TryParseColor(EditorPrefs.GetString(pbVertexColorPrefs + i), ref color))
                {
                    colors.Add(color);
                }
            }

            if (colors.Count > 0)
            {
                target.SetColors(colors);
                UnityEditor.EditorUtility.SetDirty(target);
            }
        }
        /// <summary>
        /// Reparent tile game objects into world space so that their transforms can be
        /// maintained when they are placed into their new chunks.
        /// </summary>
        /// <param name="map">New tile map.</param>
        private void ReparentTileGameObjectsIntoWorldSpace(TileData[,] map)
        {
            int mapRows    = map.GetLength(0);
            int mapColumns = map.GetLength(1);

            for (int row = 0; row < mapRows; ++row)
            {
                this.taskProgress += this.taskIncrement;
                InternalUtility.ProgressHandler("Rebuilding Tile System", "Clearing existing chunks.", this.taskProgress);

                for (int column = 0; column < mapColumns; ++column)
                {
                    var tile = map[row, column];
                    if (tile == null || tile.Empty || tile.gameObject == null)
                    {
                        continue;
                    }

                    tile.gameObject.transform.SetParent(null);
                }
            }
        }
        public static string RegisterExtension(string id, Info extensionInfo)
        {
            id = InternalUtility.Validate(id, "Extension", extensionInfo.GetType().FullName, true, true);
            if (ModExtensions.ContainsKey(id))
            {
                return(null);
            }

            extensionInfo.Id = id;
            Texture2D t = null;

            if (File.Exists(extensionInfo.LogoPath))
            {
                using (var fs = File.OpenRead(extensionInfo.LogoPath))
                    t = Texture2D.FromStream(Game1.getSingleton().GraphicsDevice, fs);
            }
            ModExtensions.Add(id, new Tuple <Info, Texture2D, GUI.Button>(extensionInfo, t,
                                                                          new GUI.Button(-1, -1, 450, 50,
                                                                                         Utility.ActiveModId + ": "
                                                                                         + extensionInfo.Name,
                                                                                         Color.White)));
            return(id);
        }
示例#30
0
        protected virtual void OnDisable()
        {
#if UNITY_EDITOR
            if (InternalUtility.IsPrefab(this))
            {
                return;
            }

            if (Application.isPlaying)
            {
#endif
            if (isAttachedToGroup)
            {
                attachedGroup.TryRemoveGraphic(this);
            }
            else if (_willBeAttached)
            {
                _groupToBeAttachedTo.TryRemoveGraphic(this);
            }
#if UNITY_EDITOR
        }
#endif
        }