Пример #1
0
        /*
         * public static void AddObjectToModel(CSGModel model, UnityEngine.Object obj)
         * {
         *  if (!model || !obj)
         *      return;
         *
         *  if (!CSGPrefabUtility.IsPrefab(model))
         *      return;
         *
         *  var asset       = CSGPrefabUtility.GetPrefabAsset(model.gameObject);
         *  var assetPath   = AssetDatabase.GetAssetPath(asset);
         *  if (!CanAddObjectToAsset(assetPath, obj))
         *      return;
         *
         *  AssetDatabase.AddObjectToAsset(obj, asset);
         * }
         *
         * public static void AddObjectsToModel(CSGModel model, UnityEngine.Object[] objs)
         * {
         *  if (!model)
         *      return;
         *
         *  if (!CSGPrefabUtility.IsPrefab(model))
         *      return;
         *
         *  var asset       = CSGPrefabUtility.GetPrefabAsset(model.gameObject);
         *  var assetPath   = AssetDatabase.GetAssetPath(asset);
         *  if (string.IsNullOrEmpty(assetPath))
         *      return;
         *
         *  foreach (var obj in objs)
         *  {
         *      if (!CanAddObjectToAsset(assetPath, obj))
         *          continue;
         *
         *      AssetDatabase.AddObjectToAsset(obj, asset);
         *  }
         * }
         *
         * public static void RemoveObjectFromModel(CSGModel model, UnityEngine.Object obj)
         * {
         #if UNITY_2018_3_OR_NEWER
         *  if (!model || !obj)
         *      return;
         *
         *  if (!CSGPrefabUtility.IsPrefab(model))
         *      return;
         *
         *  var asset       = CSGPrefabUtility.GetPrefabAsset(model.gameObject);
         *  var assetPath   = AssetDatabase.GetAssetPath(asset);
         *  if (!CanRemoveObjectFromAsset(assetPath, obj))
         *      return;
         *
         *  AssetDatabase.RemoveObjectFromAsset(obj);
         #endif
         * }
         */

        public static void RemoveObjectsFromModel(CSGModel model, UnityEngine.Object[] objs)
        {
#if UNITY_2018_3_OR_NEWER
            if (!model)
            {
                return;
            }

            if (!CSGPrefabUtility.IsPrefab(model))
            {
                return;
            }

            var asset     = CSGPrefabUtility.GetPrefabAsset(model.gameObject);
            var assetPath = AssetDatabase.GetAssetPath(asset);
            foreach (var obj in objs)
            {
                if (!obj)
                {
                    continue;
                }

                if (!CanRemoveObjectFromAsset(assetPath, obj))
                {
                    continue;
                }

                AssetDatabase.RemoveObjectFromAsset(obj);
            }
#endif
        }
Пример #2
0
        public static void AddObjectsToModel(CSGModel model, UnityEngine.Object[] objs)
        {
            if (!model)
            {
                return;
            }

            if (!CSGPrefabUtility.IsPrefab(model))
            {
                return;
            }

            var asset     = CSGPrefabUtility.GetPrefabAsset(model.gameObject);
            var assetPath = AssetDatabase.GetAssetPath(asset);

            if (string.IsNullOrEmpty(assetPath))
            {
                return;
            }

            foreach (var obj in objs)
            {
                if (!CanAddObjectToAsset(assetPath, obj))
                {
                    continue;
                }

                AssetDatabase.AddObjectToAsset(obj, asset);
            }
        }
        void CreateVisualObjects()
        {
            CleanUp();

            prevForcedGridCenter   = RealtimeCSG.CSGGrid.ForcedGridCenter;
            prevForcedGridRotation = RealtimeCSG.CSGGrid.ForcedGridRotation;

            sourceSurfaceAlignment      = PrefabSourceAlignment.AlignedFront;
            destinationSurfaceAlignment = PrefabDestinationAlignment.Default;


            visualDragGameObject = new List <GameObject>();

            foreach (var obj in dragGameObjects)
            {
                var copy = CSGPrefabUtility.Instantiate(obj);
                if (!copy)
                {
                    continue;
                }

                copy.name = obj.name;
                visualDragGameObject.Add(copy);
            }
        }
Пример #4
0
        public static void ReplaceObjectsInModel(CSGModel model, HashSet <Mesh> oldMeshes, HashSet <Mesh> newMeshes, bool skipAssetDatabaseUpdate = false)
        {
            if (!model)
            {
                return;
            }

            if (!CSGPrefabUtility.IsPrefab(model))
            {
                return;
            }

            if (!skipAssetDatabaseUpdate)
            {
                AssetDatabase.StartAssetEditing(); // We might be modifying a prefab, in which case we need to store a mesh inside it
            }
            try
            {
                var asset     = CSGPrefabUtility.GetPrefabAsset(model.gameObject);
                var assetPath = AssetDatabase.GetAssetPath(asset);
                if (string.IsNullOrEmpty(assetPath))
                {
                    return;
                }

#if UNITY_2018_3_OR_NEWER
                foreach (var oldMesh in oldMeshes)
                {
                    if (CanRemoveObjectFromAsset(assetPath, oldMesh, ignoreWhenPartOfOtherAsset: true))
                    {
                        AssetDatabase.RemoveObjectFromAsset(oldMesh);
                    }
                }
#endif

                foreach (var _newMesh in newMeshes)
                {
                    var newMesh = _newMesh;
                    if (IsObjectPartOfAnotherAsset(assetPath, newMesh))
                    {
                        // Copy the mesh
                        newMesh = newMesh.Clone();
                    }
                    if (CanAddObjectToAsset(assetPath, newMesh))
                    {
                        AssetDatabase.AddObjectToAsset(newMesh, asset);
                    }
                }
            }
            finally
            {
                if (!skipAssetDatabaseUpdate)
                {
                    AssetDatabase.StopAssetEditing();
                }
            }
        }
        void EnableVisualObjects()
        {
            if (visualDragGameObject == null ||
                visualDragGameObject.Count != dragGameObjects.Count)
            {
                CreateVisualObjects();
            }
            else
            {
                for (int i = 0; i < dragGameObjects.Count; i++)
                {
                    if (visualDragGameObject[i] == null || !visualDragGameObject[i])
                    {
                        continue;
                    }
                    visualDragGameObject[i].SetActive(dragGameObjects[i].activeSelf);
                }
            }

            int counter = 0;

            foreach (var obj in visualDragGameObject)
            {
                if (obj == null || !obj)
                {
                    continue;
                }
                var scale    = Vector3.one;
                var rotation = hoverRotation;
                var position = hoverPosition;
#if UNITY_2018_3_OR_NEWER
                if (CSGPrefabUtility.IsPrefabInstance(obj))
                {
                    var outer       = CSGPrefabUtility.GetOutermostPrefabInstanceRoot(obj);
                    var prefabAsset = CSGPrefabUtility.GetPrefabAsset(outer);
                    var transform   = prefabAsset.transform;

                    rotation *= transform.localRotation;
                    //position += transform.localPosition;
                    scale = transform.localScale;
                }
#endif
                obj.transform.rotation   = rotation;
                obj.transform.position   = position;
                obj.transform.localScale = scale;
                //	if (hoverParent != null && !CSGPrefabUtility.IsPrefabAsset(hoverParent.gameObject))
                //		obj.transform.SetParent(hoverParent, true);
                obj.transform.SetSiblingIndex(hoverSiblingIndex + counter);
                counter++;
            }
        }
Пример #6
0
        void EnableVisualObjects()
        {
            if (visualDragGameObject == null ||
                visualDragGameObject.Count != dragGameObjects.Count)
            {
                CreateVisualObjects();
            }

            var realParent = (!hoverParent || CSGPrefabUtility.IsPrefabAsset(hoverParent.gameObject)) ? null : hoverParent;

            int counter = 0;

            foreach (var obj in visualDragGameObject)
            {
                if (!obj)
                {
                    continue;
                }
                obj.transform.rotation = hoverRotation;
                obj.transform.position = hoverPosition;
                if (realParent)
                {
                    obj.transform.SetParent(realParent, true);
                }
                else
                {
                    obj.transform.parent = null;
                }
                obj.transform.SetSiblingIndex(hoverSiblingIndex + counter);
                counter++;
            }

            InternalCSGModelManager.CheckTransformChanged();
            InternalCSGModelManager.OnHierarchyModified();
            InternalCSGModelManager.UpdateMeshes(forceUpdate: true);
            MeshInstanceManager.UpdateHelperSurfaceVisibility();

            if (ignoreBrushes == null && visualDragGameObject != null)
            {
                var foundIgnoreBrushes = new List <CSGBrush>();
                foreach (var obj in visualDragGameObject)
                {
                    foundIgnoreBrushes.AddRange(obj.GetComponentsInChildren <CSGBrush>());
                }

                ignoreBrushes = foundIgnoreBrushes.ToArray();
            }
        }
Пример #7
0
        public static bool IsPrefab(CSGModel model)
        {
            if (!model)
            {
                return(false);
            }

            var parent = CSGPrefabUtility.GetPrefabAsset(model.gameObject);

            if (parent)
            {
                return(true);
            }

            return(false);
        }
Пример #8
0
        public static bool IsModelEditable(CSGModel model)
        {
            if (!model)
            {
                return(false);
            }

#if UNITY_2018_3_OR_NEWER && UNITY_EDITOR
            if (CSGPrefabUtility.AreInPrefabMode())
            {
                // Nested prefabs do not play nice with editing in scene, so it's best to edit them in prefab mode themselves
                // We only allow editing of nested prefabs when in prefab mode
                return(CSGPrefabUtility.IsEditedInPrefabMode(model));
            }
#endif
            return(model.isActiveAndEnabled);
        }
Пример #9
0
        public static bool WillModelRender(CSGModel model)
        {
            // Is our model valid ...?
            if (!IsModelEditable(model))
            {
                return(false);
            }

#if UNITY_2018_3_OR_NEWER
            if (CSGPrefabUtility.AreInPrefabMode())
            {
                if (!CSGPrefabUtility.IsEditedInPrefabMode(model))
                {
                    return(false);
                }
            }
#endif
            // Does our model have a meshRenderer?
            if (model.IsRenderable)
            {
                // If so, is it shadow-only?
//				if (model.ShadowsOnly)
//				{
                // .. and do we need to show shadow-only surfaces?
//					return CSGSettings.ShowCastShadowsSurfaces;
//				}

                // Otherwise, it is always rendering (with the exception of manually hidden surfaces)
                return(true);
            }

            // Is it a trigger and are we showing triggers?
            if (model.IsTrigger && CSGSettings.ShowTriggerSurfaces)
            {
                return(true);
            }

            // Check if it's a collider and are we showing colliders?
            if (model.HaveCollider && CSGSettings.ShowColliderSurfaces)
            {
                return(true);
            }

            // Otherwise see if we're showing surfaces culled by the CSG process ...
            return(CSGSettings.ShowCulledSurfaces);
        }
Пример #10
0
        public static void ReplaceObjectInModel(CSGModel model, UnityEngine.Object oldObj, UnityEngine.Object newObj, bool skipAssetDatabaseUpdate = false)
        {
            if (!model ||
                oldObj == newObj)
            {
                return;
            }

            if (!CSGPrefabUtility.IsPrefab(model))
            {
                return;
            }

            if (!skipAssetDatabaseUpdate)
            {
                AssetDatabase.StartAssetEditing(); // We might be modifying a prefab, in which case we need to store a mesh inside it
            }
            try
            {
                var asset     = CSGPrefabUtility.GetPrefabAsset(model.gameObject);
                var assetPath = AssetDatabase.GetAssetPath(asset);
#if UNITY_2018_3_OR_NEWER
                if (oldObj)
                {
                    if (CanRemoveObjectFromAsset(assetPath, oldObj))
                    {
                        AssetDatabase.RemoveObjectFromAsset(oldObj);
                    }
                }
#endif
                if (newObj)
                {
                    if (CanAddObjectToAsset(assetPath, newObj))
                    {
                        AssetDatabase.AddObjectToAsset(newObj, asset);
                    }
                }
            }
            finally
            {
                if (!skipAssetDatabaseUpdate)
                {
                    AssetDatabase.StopAssetEditing();
                }
            }
        }
Пример #11
0
        public static void AddObjectToModel(CSGModel model, UnityEngine.Object obj)
        {
            if (!model || !obj)
            {
                return;
            }

            if (!CSGPrefabUtility.IsPrefab(model))
            {
                return;
            }

            var asset     = CSGPrefabUtility.GetPrefabAsset(model.gameObject);
            var assetPath = AssetDatabase.GetAssetPath(asset);

            if (!CanAddObjectToAsset(assetPath, obj))
            {
                return;
            }

            AssetDatabase.AddObjectToAsset(obj, asset);
        }
Пример #12
0
        public static void RemoveObjectFromModel(CSGModel model, UnityEngine.Object obj)
        {
#if UNITY_2018_3_OR_NEWER
            if (!model || !obj)
            {
                return;
            }

            if (!CSGPrefabUtility.IsPrefab(model))
            {
                return;
            }

            var asset     = CSGPrefabUtility.GetPrefabAsset(model.gameObject);
            var assetPath = AssetDatabase.GetAssetPath(asset);
            if (!CanRemoveObjectFromAsset(assetPath, obj))
            {
                return;
            }

            AssetDatabase.RemoveObjectFromAsset(obj);
#endif
        }
Пример #13
0
        public static Transform FindParentToAssignTo(LegacyBrushIntersection intersection)
        {
            if (intersection.brush == null ||
                CSGPrefabUtility.IsPrefabAsset(intersection.brush.gameObject))
            {
                var lastModel = SelectionUtility.LastUsedModel;
                if (lastModel == null ||
                    CSGPrefabUtility.IsPrefabAsset(lastModel.gameObject))
                {
                    return(null);
                }

                return(lastModel.transform);
            }

            var hoverParent = intersection.brush.transform.parent;
            var iterator    = hoverParent;

            while (iterator != null)
            {
                var node = iterator.GetComponent <CSGNode>();
                if (node != null)
                {
                    hoverParent = node.transform;
                }
                iterator = iterator.transform.parent;
            }
            if (!hoverParent)
            {
                return(null);
            }
            if (CSGPrefabUtility.GetCorrespondingObjectFromSource(hoverParent.gameObject) != null)
            {
                return(null);
            }
            return(hoverParent);
        }
Пример #14
0
        static void OnEditModeSelectionSceneGUI()
        {
            CSG_GUIStyleUtility.InitStyles();
            if (CSG_GUIStyleUtility.brushEditModeNames == null ||
                CSG_GUIStyleUtility.brushEditModeNames.Length == 0)
            {
                return;
            }

            var oldSkin = GUI.skin;

            CSG_GUIStyleUtility.SetDefaultGUISkin();
            GUILayout.BeginHorizontal(CSG_GUIStyleUtility.ContentEmpty);
            {
                GUIStyle windowStyle = GUI.skin.window;

                float topBarSize = 20;
#if UNITY_2018_3_OR_NEWER
                if (CSGPrefabUtility.AreInPrefabMode())
                {
                    topBarSize += 25;
                }
#endif


                var bounds = new Rect(10, 10 + topBarSize, 500, 40);

                GUILayout.BeginArea(bounds, ContentTitleLabel, windowStyle);
                {
                    //GUILayout.Space(bounds.height);
                    Rect editModeBounds;

                    CSG_GUIStyleUtility.InitStyles();
                    EditorGUI.BeginChangeCheck();
                    var newEditMode = (ToolEditMode)CSG_EditorGUIUtility.ToolbarWrapped((int)EditModeManager.EditMode, ref editModeRects, out editModeBounds, CSG_GUIStyleUtility.brushEditModeContent, CSG_GUIStyleUtility.brushEditModeTooltips, yOffset: 20, areaWidth: bounds.width);
                    //var newEditMode = (ToolEditMode)GUILayout.Toolbar((int)CSGBrushEditorManager.EditMode, GUIStyleUtility.brushEditModeContent, GUIStyleUtility.brushEditModeTooltips);
                    if (EditorGUI.EndChangeCheck())
                    {
                        EditModeManager.EditMode = newEditMode;
                        CSG_EditorGUIUtility.RepaintAll();
                    }

                    var buttonArea = bounds;
                    buttonArea.x      = bounds.width - 17;
                    buttonArea.y      = 2;
                    buttonArea.height = 13;
                    buttonArea.width  = 13;
                    if (GUI.Button(buttonArea, GUIContent.none, "WinBtnClose"))
                    {
                        EditModeToolWindowSceneGUI.GetWindow();
                    }
                    TooltipUtility.SetToolTip(CSG_GUIStyleUtility.PopOutTooltip, buttonArea);

                    var versionWidth = CSG_GUIStyleUtility.versionLabelStyle.CalcSize(VersionLabel);
                    var versionArea  = bounds;
                    versionArea.x      = bounds.width - (17 + versionWidth.x);
                    versionArea.y      = 1;
                    versionArea.height = 15;
                    versionArea.width  = versionWidth.x;
                    GUI.Label(versionArea, VersionLabel, CSG_GUIStyleUtility.versionLabelStyle);
                }
                GUILayout.EndArea();

                int controlID = GUIUtility.GetControlID(SceneViewBrushEditorOverlayHash, FocusType.Keyboard, bounds);
                switch (Event.current.GetTypeForControl(controlID))
                {
                case EventType.MouseDown:       { if (bounds.Contains(Event.current.mousePosition))
                                                  {
                                                      GUIUtility.hotControl = controlID; GUIUtility.keyboardControl = controlID; EditorGUIUtility.editingTextField = false; Event.current.Use();
                                                  }
                                                  break; }

                case EventType.MouseMove:       { if (bounds.Contains(Event.current.mousePosition))
                                                  {
                                                      Event.current.Use();
                                                  }
                                                  break; }

                case EventType.MouseUp:         { if (GUIUtility.hotControl == controlID)
                                                  {
                                                      GUIUtility.hotControl = 0; GUIUtility.keyboardControl = 0; Event.current.Use();
                                                  }
                                                  break; }

                case EventType.MouseDrag:       { if (GUIUtility.hotControl == controlID)
                                                  {
                                                      Event.current.Use();
                                                  }
                                                  break; }

                case EventType.ScrollWheel: { if (bounds.Contains(Event.current.mousePosition))
                                              {
                                                  Event.current.Use();
                                              }
                                              break; }
                }
            }
            GUILayout.EndHorizontal();
            GUI.skin = oldSkin;
        }
        public bool ValidateDrop(SceneView sceneView)
        {
            if (!sceneView)
            {
                return(false);
            }

            Reset();
            if (DragAndDrop.objectReferences == null ||
                DragAndDrop.objectReferences.Length == 0)
            {
                dragGameObjects = null;
                return(false);
            }

            bool found = false;

            dragGameObjects = new List <GameObject>();
            foreach (var obj in DragAndDrop.objectReferences)
            {
                var gameObject = obj as GameObject;
                if (gameObject == null)
                {
                    continue;
                }

                if (!CSGPrefabUtility.IsPrefabAsset(gameObject))
                {
                    continue;
                }

                dragGameObjects.Add(gameObject);

                if (gameObject.GetComponentInChildren <Renderer>() != null)
                {
                    found = true;
                }
            }
            if (!found || dragGameObjects.Count != 1)
            {
                dragGameObjects = null;
                return(false);
            }

            var dragGameObjectBounds = new AABB();

            dragGameObjectBounds.Reset();
            foreach (var gameObject in dragGameObjects)
            {
                var renderers = gameObject.GetComponentsInChildren <Renderer>();
                if (renderers.Length == 0)
                {
                    continue;
                }
                foreach (var renderer in renderers)
                {
                    var bounds = renderer.bounds;
                    dragGameObjectBounds.Extend(bounds.min);
                    dragGameObjectBounds.Extend(bounds.max);
                }
            }

            if (!dragGameObjectBounds.Valid)
            {
                dragGameObjectBounds.Extend(MathConstants.zeroVector3);
            }

            projectedBounds = new Vector3[8];
            BoundsUtilities.GetBoundsCornerPoints(dragGameObjectBounds, projectedBounds);

            /*
             * var upPlane = new Plane(MathConstants.upVector3, MathConstants.zeroVector3);
             * for (int i = 7; i >= 0; i--)
             * {
             *      projectedBounds[i] = upPlane.Project(projectedBounds[i]);
             *      for (int j = i+1; j < projectedBounds.Length; j++)
             *      {
             *              if (projectedBounds[i] == projectedBounds[j])
             *              {
             *                      ArrayUtility.RemoveAt(ref projectedBounds, j);
             *                      break;
             *              }
             *      }
             * }*/

            haveNoParent = false;
            return(true);
        }
Пример #16
0
        public bool UpdateSelection(HashSet <CSGNode> newTargetNodes, HashSet <Transform> newTargetOthers)
        {
            if (newTargetNodes == null)
            {
                newTargetNodes = new HashSet <CSGNode>();
            }
            if (newTargetOthers == null)
            {
                newTargetOthers = new HashSet <Transform>();
            }

            this.RemovedNodes  = null;
            this.RemovedOthers = null;

            this.AddedNodes  = null;
            this.AddedOthers = null;

            var foundRemovedNodes = new List <CSGNode>();

            if (this.NodeTargets != null &&
                this.NodeTargets.Length > 0)
            {
                if (newTargetNodes.Count == 0)
                {
                    foundRemovedNodes.AddRange(this.NodeTargets);
                }
                else
                {
                    for (int i = 0; i < this.NodeTargets.Length; i++)
                    {
                        if (!this.NodeTargets[i] ||
                            !newTargetNodes.Contains(this.NodeTargets[i]))
                        {
                            foundRemovedNodes.Add(this.NodeTargets[i]);
                        }
                    }
                }
            }

            var foundRemovedOthers = new List <Transform>();

            if (this.OtherTargets != null &&
                this.OtherTargets.Length > 0)
            {
                if (newTargetOthers.Count == 0)
                {
                    foundRemovedOthers.AddRange(this.OtherTargets);
                }
                else
                {
                    for (int i = 0; i < this.OtherTargets.Length; i++)
                    {
                        if (!this.OtherTargets[i] ||
                            !newTargetOthers.Contains(this.OtherTargets[i]))
                        {
                            foundRemovedOthers.Add(this.OtherTargets[i]);
                        }
                    }
                }
            }

            var originalTargetNodeCount  = (this.NodeTargets == null) ? 0 : this.NodeTargets.Length;
            var originalTargetOtherCount = (this.OtherTargets == null) ? 0 : this.OtherTargets.Length;

            // If our counts are the same and nothing is removed (and nothing could've been added), nothing has changed.
            if (newTargetNodes.Count == originalTargetNodeCount &&
                newTargetOthers.Count == originalTargetOtherCount &&
                foundRemovedNodes.Count == 0 &&
                foundRemovedOthers.Count == 0)
            {
                return(false);
            }

            Validate();

            foreach (var node in foundRemovedNodes)
            {
                ArrayUtility.Remove(ref this.NodeTargets, node);

                var brush = node as CSGBrush;
                if (brush != null)
                {
                    ArrayUtility.Remove(ref this.BrushTargets, brush);
                    continue;
                }
                var operation = node as CSGOperation;
                if (node is CSGOperation)
                {
                    ArrayUtility.Remove(ref this.OperationTargets, operation);
                    continue;
                }
                var model = node as CSGModel;
                if (node is CSGModel)
                {
                    ArrayUtility.Remove(ref this.ModelTargets, model);
                    continue;
                }
            }

            foreach (var other in foundRemovedOthers)
            {
                ArrayUtility.Remove(ref this.OtherTargets, other);
            }

            var foundAddedNodes = new List <CSGNode>();

            foreach (var node in newTargetNodes)
            {
                if (this.NodeTargets != null &&
                    ArrayUtility.Contains(this.NodeTargets, node))
                {
                    continue;
                }

                if (this.NodeTargets == null)
                {
                    this.NodeTargets = new CSGNode[] { node };
                }
                else
                {
                    ArrayUtility.Add(ref this.NodeTargets, node);
                }

                foundAddedNodes.Add(node);

                if (CSGPrefabUtility.IsPrefabAsset(node.gameObject))
                {
                    continue;
                }

                var brush = node as CSGBrush;
                if (brush != null)
                {
                    if (this.BrushTargets == null)
                    {
                        this.BrushTargets = new CSGBrush[] { brush }
                    }
                    ;
                    else
                    {
                        ArrayUtility.Add(ref this.BrushTargets, brush);
                    }
                    continue;
                }
                var operation = node as CSGOperation;
                if (node is CSGOperation)
                {
                    if (this.OperationTargets == null)
                    {
                        this.OperationTargets = new CSGOperation[] { operation }
                    }
                    ;
                    else
                    {
                        ArrayUtility.Add(ref this.OperationTargets, operation);
                    }
                    continue;
                }
                var model = node as CSGModel;
                if (node is CSGModel)
                {
                    if (this.ModelTargets == null)
                    {
                        this.ModelTargets = new CSGModel[] { model }
                    }
                    ;
                    else
                    {
                        ArrayUtility.Add(ref this.ModelTargets, model);
                    }
                    continue;
                }
            }

            var foundAddedOthers = new List <Transform>();

            foreach (var other in newTargetOthers)
            {
                if (this.OtherTargets != null &&
                    ArrayUtility.Contains(this.OtherTargets, other))
                {
                    continue;
                }

                if (this.OtherTargets == null)
                {
                    this.OtherTargets = new Transform[] { other }
                }
                ;
                else
                {
                    ArrayUtility.Add(ref this.OtherTargets, other);
                }
                foundAddedOthers.Add(other);
            }

            for (int i = foundAddedNodes.Count - 1; i >= 0; i--)
            {
                var node  = foundAddedNodes[i];
                var brush = node as CSGBrush;
                if (brush != null)
                {
                    if (brush.ChildData == null ||
                        brush.ChildData.Model == null)
                    {
                        continue;
                    }

                    var childModel = brush.ChildData.Model;
                    if (ModelTraits.IsModelEditable(childModel))
                    {
                        SelectionUtility.LastUsedModel = childModel;
                    }
                    break;
                }
                var operation = node as CSGOperation;
                if (operation != null)
                {
                    if (operation.ChildData == null ||
                        operation.ChildData.Model == null)
                    {
                        continue;
                    }

                    SelectionUtility.LastUsedModel = operation.ChildData.Model;
                    break;
                }
                var model = node as CSGModel;
                if (ModelTraits.IsModelEditable(model))
                {
                    SelectionUtility.LastUsedModel = model;
                    break;
                }
            }

            this.RemovedNodes  = foundRemovedNodes.ToArray();
            this.RemovedOthers = foundRemovedOthers.ToArray();

            this.AddedNodes  = foundAddedNodes.ToArray();
            this.AddedOthers = foundAddedOthers.ToArray();

            return(foundAddedNodes.Count > 0 || foundRemovedNodes.Count > 0 || foundAddedOthers.Count > 0 || foundRemovedOthers.Count > 0);
        }
Пример #17
0
        void CreateVisualObjects(bool inSceneView = false)
        {
            CleanUp();

            prevForcedGridCenter   = RealtimeCSG.CSGGrid.ForcedGridCenter;
            prevForcedGridRotation = RealtimeCSG.CSGGrid.ForcedGridRotation;

            sourceSurfaceAlignment      = PrefabSourceAlignment.AlignedFront;
            destinationSurfaceAlignment = PrefabDestinationAlignment.AlignToSurface;


            visualDragGameObject = new List <GameObject>();

            var foundTransforms = new List <Transform>();

            foreach (var obj in dragGameObjects)
            {
                foundTransforms.AddRange(obj.GetComponentsInChildren <Transform>());
                CSGNode node = obj.GetComponent <CSGNode>();
                if (!node)
                {
                    continue;
                }
                sourceSurfaceAlignment      = node.PrefabSourceAlignment;
                destinationSurfaceAlignment = node.PrefabDestinationAlignment;

                bool createCopyInsteadOfInstance = node && node.PrefabBehaviour == PrefabInstantiateBehaviour.Copy;

                GameObject copy = CSGPrefabUtility.Instantiate(obj, createCopyInsteadOfInstance);
                if (!copy)
                {
                    continue;
                }


                copy.name = obj.name;
                visualDragGameObject.Add(copy);
            }

            ignoreTransforms = new HashSet <Transform>(foundTransforms);

            if (inSceneView)
            {
                var model = SelectionUtility.LastUsedModel;
                if (model && !containsModel)
                {
                    var parent  = model.transform;
                    int counter = 0;
                    foreach (var obj in visualDragGameObject)
                    {
                        if (!obj)
                        {
                            continue;
                        }
                        if (obj.activeSelf)
                        {
                            obj.transform.SetParent(parent, false);
                            obj.transform.SetSiblingIndex(hoverSiblingIndex + counter);
                            counter++;
                        }
                    }
                }
            }
            else
            {
                var parent  = hoverParent;
                int counter = 0;
                foreach (var obj in visualDragGameObject)
                {
                    if (!obj)
                    {
                        continue;
                    }
                    if (obj.activeSelf)
                    {
                        obj.transform.SetParent(parent, false);
                        obj.transform.SetSiblingIndex(hoverSiblingIndex + counter);
                        counter++;
                    }
                }
            }
        }
Пример #18
0
        public bool ValidateDrop(SceneView sceneView)
        {
            if (!sceneView)
            {
                return(false);
            }

            Reset();
            if (DragAndDrop.objectReferences == null ||
                DragAndDrop.objectReferences.Length == 0)
            {
                dragGameObjects = null;
                return(false);
            }

            dragGameObjects = new List <GameObject>();
            containsModel   = false;
            foreach (var obj in DragAndDrop.objectReferences)
            {
                var gameObject = obj as GameObject;
                if (gameObject == null)
                {
                    continue;
                }

                if (gameObject.GetComponent <CSGNode>() == null)
                {
                    continue;
                }

                if (gameObject.GetComponentsInChildren <CSGBrush>() == null)
                {
                    continue;
                }

                if (!CSGPrefabUtility.IsPrefabAsset(gameObject))
                {
                    continue;
                }

                dragGameObjects.Add(gameObject);
                containsModel = containsModel || (gameObject.GetComponent <CSGModel>() != null);
            }
            if (dragGameObjects.Count != 1)
            {
                dragGameObjects = null;
                return(false);
            }

            var dragGameObjectBounds = new AABB();

            dragGameObjectBounds.Reset();
            foreach (var gameObject in dragGameObjects)
            {
                var brushes = gameObject.GetComponentsInChildren <CSGBrush>();
                if (brushes.Length == 0)
                {
                    continue;
                }
                dragGameObjectBounds.Add(BoundsUtilities.GetLocalBounds(brushes, gameObject.transform.worldToLocalMatrix));
            }

            if (!dragGameObjectBounds.Valid)
            {
                dragGameObjectBounds.Extend(MathConstants.zeroVector3);
            }

            projectedBounds = new Vector3[8];
            BoundsUtilities.GetBoundsCornerPoints(dragGameObjectBounds, projectedBounds);
            haveNoParent = false;
            return(true);
        }
Пример #19
0
        static public void OnInspectorGUI(Editor editor, UnityEngine.Object[] targets)
        {
            TooltipUtility.InitToolTip(editor);
            try
            {
                var models = new CSGModel[targets.Length];

                for (int i = targets.Length - 1; i >= 0; i--)
                {
                    models[i] = targets[i] as CSGModel;
                    if (!models[i])
                    {
                        ArrayUtility.RemoveAt(ref models, i);
                    }
                }

                CSG_GUIStyleUtility.InitStyles();
                ShowRealtimeCSGDisabledMessage();

                if (models.Length > 0 && models.Length == targets.Length)
                {
                    CSGModelComponentInspectorGUI.OnInspectorGUI(targets);
                    return;
                }

                var filteredSelection = EditModeManager.FilteredSelection;
                var targetNodes       = filteredSelection.NodeTargets;
                var targetModels      = filteredSelection.ModelTargets;
                var targetBrushes     = filteredSelection.BrushTargets;
                var targetOperations  = filteredSelection.OperationTargets;
                if (targetNodes == null)
                {
                    return;
                }



                bool?isPrefab = false;
                PrefabInstantiateBehaviour?prefabBehaviour            = PrefabInstantiateBehaviour.Reference;
                PrefabSourceAlignment?     prefabSourceAlignment      = PrefabSourceAlignment.AlignedTop;
                PrefabDestinationAlignment?prefabDestinationAlignment = PrefabDestinationAlignment.AlignToSurface;

                if (targetNodes.Length > 0)
                {
                    var gameObject = targetNodes[0].gameObject;
                    isPrefab                   = CSGPrefabUtility.IsPrefabAsset(gameObject);
                    prefabBehaviour            = targetNodes[0].PrefabBehaviour;
                    prefabSourceAlignment      = targetNodes[0].PrefabSourceAlignment;
                    prefabDestinationAlignment = targetNodes[0].PrefabDestinationAlignment;
                    for (int i = 1; i < targetNodes.Length; i++)
                    {
                        gameObject = targetNodes[i].gameObject;

                        var currentIsPrefab                   = CSGPrefabUtility.IsPrefabAsset(gameObject);
                        var currentPrefabBehaviour            = targetNodes[i].PrefabBehaviour;
                        var currentPrefabSourceAlignment      = targetNodes[i].PrefabSourceAlignment;
                        var currentPrefabDestinationAlignment = targetNodes[i].PrefabDestinationAlignment;
                        if (isPrefab.HasValue && isPrefab.Value != currentIsPrefab)
                        {
                            isPrefab = null;
                        }
                        if (prefabBehaviour.HasValue && prefabBehaviour.Value != currentPrefabBehaviour)
                        {
                            prefabBehaviour = null;
                        }
                        if (prefabSourceAlignment.HasValue && prefabSourceAlignment.Value != currentPrefabSourceAlignment)
                        {
                            prefabSourceAlignment = null;
                        }
                        if (prefabDestinationAlignment.HasValue && prefabDestinationAlignment.Value != currentPrefabDestinationAlignment)
                        {
                            prefabDestinationAlignment = null;
                        }
                    }
                }

                GUILayout.BeginVertical(GUI.skin.box);
                {
                    if (isPrefab.HasValue && isPrefab.Value)
                    {
                        EditorGUILayout.LabelField(PrefabLabelContent);
                    }
                    else
                    {
                        EditorGUILayout.LabelField(RaySnappingLabelContent);
                        TooltipUtility.SetToolTip(RaySnappingBehaviourTooltip);
                    }

                    EditorGUI.indentLevel++;
                    {
                        if (isPrefab.HasValue && isPrefab.Value)
                        {
                            EditorGUI.showMixedValue = !prefabBehaviour.HasValue;
                            var prefabBehavour = prefabBehaviour.HasValue ? prefabBehaviour.Value : PrefabInstantiateBehaviour.Reference;
                            EditorGUI.BeginChangeCheck();
                            {
                                prefabBehavour = (PrefabInstantiateBehaviour)EditorGUILayout.EnumPopup(PrefabInstantiateBehaviourContent, prefabBehavour);
                                TooltipUtility.SetToolTip(PrefabInstantiateBehaviourTooltip);
                            }
                            if (EditorGUI.EndChangeCheck())
                            {
                                Undo.RecordObjects(targetNodes, "Changed CSG operation of nodes");
                                for (int i = 0; i < targetNodes.Length; i++)
                                {
                                    targetNodes[i].PrefabBehaviour = prefabBehavour;
                                }
                            }
                            EditorGUI.showMixedValue = false;
                        }


                        EditorGUI.showMixedValue = !prefabDestinationAlignment.HasValue;
                        var destinationAlignment = prefabDestinationAlignment.HasValue ? prefabDestinationAlignment.Value : PrefabDestinationAlignment.AlignToSurface;
                        EditorGUI.BeginChangeCheck();
                        {
                            destinationAlignment = (PrefabDestinationAlignment)EditorGUILayout.EnumPopup(DestinationAlignmentContent, destinationAlignment);
                            TooltipUtility.SetToolTip(DestinationAlignmentTooltip);
                        }
                        if (EditorGUI.EndChangeCheck())
                        {
                            Undo.RecordObjects(targetNodes, "Changed CSG operation of nodes");
                            for (int i = 0; i < targetNodes.Length; i++)
                            {
                                targetNodes[i].PrefabDestinationAlignment = destinationAlignment;
                            }
                        }
                        EditorGUI.showMixedValue = false;


                        EditorGUI.showMixedValue = !prefabSourceAlignment.HasValue;
                        var sourceAlignment = prefabSourceAlignment.HasValue ? prefabSourceAlignment.Value : PrefabSourceAlignment.AlignedFront;
                        EditorGUI.BeginChangeCheck();
                        {
                            sourceAlignment = (PrefabSourceAlignment)EditorGUILayout.EnumPopup(SourceAlignmentContent, sourceAlignment);
                            TooltipUtility.SetToolTip(SourceAlignmentTooltip);
                        }
                        if (EditorGUI.EndChangeCheck())
                        {
                            Undo.RecordObjects(targetNodes, "Changed CSG operation of nodes");
                            for (int i = 0; i < targetNodes.Length; i++)
                            {
                                targetNodes[i].PrefabSourceAlignment = sourceAlignment;
                            }
                        }
                        EditorGUI.showMixedValue = false;
                    }
                    EditorGUI.indentLevel--;
                }
                GUILayout.EndVertical();
                GUILayout.Space(10);


                if (targetModels.Length == 0)
                {
                    int              invalidOperationType = 999;
                    bool?            handleAsOne          = null;
                    bool             selMixedValues       = false;
                    CSGOperationType operationType        = (CSGOperationType)invalidOperationType;
                    bool             opMixedValues        = false;
                    if (targetBrushes.Length > 0)
                    {
                        operationType = targetBrushes[0].OperationType;
                    }
                    for (int b = 1; b < targetBrushes.Length; b++)
                    {
                        var brush = targetBrushes[b];
                        if (operationType != brush.OperationType)
                        {
                            opMixedValues = true;
                        }
                    }
                    foreach (var operation in targetOperations)
                    {
                        if (operationType == (CSGOperationType)invalidOperationType)
                        {
                            operationType = operation.OperationType;
                        }
                        else
                        if (operationType != operation.OperationType)
                        {
                            opMixedValues = true;
                        }

                        if (!handleAsOne.HasValue)
                        {
                            handleAsOne = operation.HandleAsOne;
                        }
                        else
                        if (handleAsOne.Value != operation.HandleAsOne)
                        {
                            selMixedValues = true;
                        }
                    }
                    GUILayout.BeginVertical(GUI.skin.box);
                    {
                        bool passThroughValue = false;
                        if (targetBrushes.Length == 0 && targetOperations.Length > 0)                         // only operations
                        {
                            bool?passThrough = targetOperations[0].PassThrough;
                            for (int i = 1; i < targetOperations.Length; i++)
                            {
                                if (passThrough.HasValue && passThrough.Value != targetOperations[i].PassThrough)
                                {
                                    passThrough = null;
                                    break;
                                }
                            }

                            opMixedValues = !passThrough.HasValue || passThrough.Value;

                            var ptMixedValues = !passThrough.HasValue;
                            passThroughValue = passThrough.HasValue ? passThrough.Value : false;
                            if (CSG_EditorGUIUtility.PassThroughButton(passThroughValue, ptMixedValues))
                            {
                                Undo.RecordObjects(targetNodes, "Changed CSG operation of nodes");
                                foreach (var operation in targetOperations)
                                {
                                    operation.PassThrough = true;
                                }
                                InternalCSGModelManager.CheckForChanges();
                                EditorApplication.RepaintHierarchyWindow();
                            }

                            if (passThroughValue)
                            {
                                operationType = (CSGOperationType)255;
                            }
                        }
                        EditorGUI.BeginChangeCheck();
                        {
                            operationType = CSG_EditorGUIUtility.ChooseOperation(operationType, opMixedValues);
                        }
                        if (EditorGUI.EndChangeCheck())
                        {
                            Undo.RecordObjects(targetNodes, "Changed CSG operation of nodes");
                            foreach (var brush in targetBrushes)
                            {
                                brush.OperationType = operationType;
                            }
                            foreach (var operation in targetOperations)
                            {
                                operation.PassThrough   = false;
                                operation.OperationType = operationType;
                            }
                            InternalCSGModelManager.CheckForChanges();
                            EditorApplication.RepaintHierarchyWindow();
                        }
                    }
                    GUILayout.EndVertical();

                    if (targetOperations.Length == 0 && targetModels.Length == 0)
                    {
                        GUILayout.Space(10);
                        if (targetBrushes.Length == 1)
                        {
                            GUILayout.BeginVertical(GUI.skin.box);
                            {
                                EditorGUI.indentLevel++;
                                OpenSurfaces = EditorGUILayout.Foldout(OpenSurfaces, SurfacesContent);
                                EditorGUI.indentLevel--;
                                if (OpenSurfaces)
                                {
                                    var targetShape     = targetBrushes[0].Shape;
                                    var texGens         = targetShape.TexGens;
                                    var texGenFlagArray = targetShape.TexGenFlags;
                                    for (int t = 0; t < texGens.Length; t++)
                                    {
                                        GUILayout.Space(2);

                                        var texGenFlags = texGenFlagArray[t];
                                        var material    = targetShape.TexGens[t].RenderMaterial;
                                        var physicsMat  = targetShape.TexGens[t].PhysicsMaterial;
                                        EditorGUI.BeginChangeCheck();
                                        {
                                            GUILayout.BeginHorizontal();
                                            {
                                                GUILayout.Space(4);
                                                material = CSG_EditorGUIUtility.MaterialImage(material);
                                                GUILayout.Space(2);
                                                GUILayout.BeginVertical();
                                                {
                                                    //EditorGUI.BeginDisabledGroup(texGenFlags != TexGenFlags.None);
                                                    {
                                                        material = EditorGUILayout.ObjectField(material, typeof(Material), true) as Material;
                                                    }
                                                    //EditorGUI.EndDisabledGroup();
                                                    physicsMat = EditorGUILayout.ObjectField(physicsMat, typeof(PhysicMaterial), true) as PhysicMaterial;

                                                    texGenFlags = EditModeCommonGUI.OnSurfaceFlagButtons(texGenFlags);
                                                }
                                                GUILayout.EndVertical();
                                                GUILayout.Space(4);
                                            }
                                            GUILayout.EndHorizontal();
                                        }
                                        if (EditorGUI.EndChangeCheck())
                                        {
                                            var selectedBrushSurfaces = new []
                                            {
                                                new SelectedBrushSurface(targetBrushes[0], t)
                                            };
                                            using (new UndoGroup(selectedBrushSurfaces, "discarding surface"))
                                            {
                                                texGenFlagArray[t] = texGenFlags;
                                                targetShape.TexGens[t].RenderMaterial  = material;
                                                targetShape.TexGens[t].PhysicsMaterial = physicsMat;
                                            }
                                        }
                                        GUILayout.Space(4);
                                    }
                                }
                            }
                            GUILayout.EndVertical();
                        }
                    }

                    if (handleAsOne.HasValue)
                    {
                        EditorGUI.BeginChangeCheck();
                        {
                            EditorGUI.showMixedValue = selMixedValues;
                            handleAsOne = EditorGUILayout.Toggle(HandleAsOneLabel, handleAsOne.Value);
                        }
                        if (EditorGUI.EndChangeCheck())
                        {
                            Undo.RecordObjects(targetNodes, "Changed CSG operation 'Handle as one object'");
                            foreach (var operation in targetOperations)
                            {
                                operation.HandleAsOne = handleAsOne.Value;
                            }
                            EditorApplication.RepaintHierarchyWindow();
                        }
                    }
                }

#if false
                if (targetNodes.Length == 1)
                {
                    var node  = targetNodes[0];
                    var brush = node as CSGBrush;
                    if (brush != null)
                    {
                        var brush_cache = CSGSceneManager.GetBrushCache(brush);
                        if (brush_cache == null ||
                            brush_cache.childData == null ||
                            brush_cache.childData.modelTransform == null)
                        {
                            EditorGUILayout.LabelField("brush-cache: null");
                        }
                        else
                        {
                            EditorGUILayout.LabelField("node-id: " + brush.brushNodeID);
                        }
                    }
                    var operation = node as CSGOperation;
                    if (operation != null)
                    {
                        var operation_cache = CSGSceneManager.GetOperationCache(operation);
                        if (operation_cache == null ||
                            operation_cache.childData == null ||
                            operation_cache.childData.modelTransform == null)
                        {
                            EditorGUILayout.LabelField("operation-cache: null");
                        }
                        else
                        {
                            EditorGUILayout.LabelField("operation-id: " + operation.operationNodeID);
                        }
                    }
                    var model = node as CSGModel;
                    if (model != null)
                    {
                        var model_cache = CSGSceneManager.GetModelCache(model);
                        if (model_cache == null ||
                            model_cache.meshContainer == null)
                        {
                            EditorGUILayout.LabelField("model-cache: null");
                        }
                        else
                        {
                            EditorGUILayout.LabelField("model-id: " + model.modelNodeID);
                        }
                    }
                }
#endif
            }
            finally
            {
                TooltipUtility.DrawToolTip(getLastRect: true, goUp: true);
            }
        }
Пример #20
0
        public static Transform[] CloneTargets(SetTransformation setTransform = null)
        {
            if (instance.filteredSelection.NodeTargets.Length == 0)
            {
                return(new Transform[0]);
            }

            var groupId = Undo.GetCurrentGroup();
            //Undo.IncrementCurrentGroup();

            var newTargets    = new GameObject[instance.filteredSelection.NodeTargets.Length];
            var newTransforms = new Transform[instance.filteredSelection.NodeTargets.Length];

            for (int i = 0; i < instance.filteredSelection.NodeTargets.Length; i++)
            {
                var originalGameObject = instance.filteredSelection.NodeTargets[i].gameObject;
                var originalTransform  = originalGameObject.GetComponent <Transform>();

                newTargets[i] = CSGPrefabUtility.Instantiate(originalGameObject);
                var newTransform = newTargets[i].GetComponent <Transform>();
                if (originalTransform.parent != null)
                {
                    newTransform.SetParent(originalTransform.parent, false);
                    newTransform.SetSiblingIndex(originalTransform.GetSiblingIndex() + 1);
                    newTransform.name = GameObjectUtility.GetUniqueNameForSibling(originalTransform.parent, originalTransform.name);
                }
                if (setTransform == null)
                {
                    newTransform.localScale    = originalTransform.localScale;
                    newTransform.localPosition = originalTransform.localPosition;
                    newTransform.localRotation = originalTransform.localRotation;
                }
                else
                {
                    setTransform(newTransform, originalTransform);
                }

                var childBrushes = newTargets[i].GetComponentsInChildren <CSGBrush>();

                Dictionary <uint, uint> uniqueSmoothingGroups = new Dictionary <uint, uint>();
                foreach (var childBrush in childBrushes)
                {
                    for (int g = 0; g < childBrush.Shape.TexGens.Length; g++)
                    {
                        var smoothingGroup = childBrush.Shape.TexGens[g].SmoothingGroup;
                        if (smoothingGroup == 0)
                        {
                            continue;
                        }

                        uint newSmoothingGroup;
                        if (!uniqueSmoothingGroups.TryGetValue(smoothingGroup, out newSmoothingGroup))
                        {
                            newSmoothingGroup = SurfaceUtility.FindUnusedSmoothingGroupIndex();
                            uniqueSmoothingGroups[smoothingGroup] = newSmoothingGroup;
                        }

                        childBrush.Shape.TexGens[g].SmoothingGroup = newSmoothingGroup;
                    }
                }

                newTransforms[i] = newTransform;
                Undo.RegisterCreatedObjectUndo(newTargets[i], "Created clone of " + originalGameObject.name);
            }

            Selection.objects = newTargets;
            Undo.CollapseUndoOperations(groupId);

            return(newTransforms);
        }
Пример #21
0
        public static void OnPrefabSaving(GameObject obj)
        {
            var foundGeneratedMeshes = obj.GetComponentsInChildren <GeneratedMeshes>();

            if (foundGeneratedMeshes.Length == 0)
            {
                return;
            }

            var defaultModel = InternalCSGModelManager.GetDefaultCSGModelForObject(obj.transform);

            newMeshes.Clear();
            foreach (var generatedMeshesInstance in foundGeneratedMeshes)
            {
                if (generatedMeshesInstance.owner == defaultModel)
                {
                    continue;
                }

                foreach (var generatedMeshInstance in generatedMeshesInstance.GetComponentsInChildren <GeneratedMeshInstance>())
                {
                    if (!generatedMeshInstance) // possible when it's deleted in a prefab
                    {
                        continue;
                    }
                    foundGeneratedMeshInstances.Add(generatedMeshInstance);
                    if (generatedMeshInstance.SharedMesh)
                    {
                        newMeshes.Add(generatedMeshInstance.SharedMesh);
                    }
                }

                foreach (var helperSurface in generatedMeshesInstance.HelperSurfaces)
                {
                    foundHelperSurfaces.Add(helperSurface);
                    newMeshes.Add(helperSurface.SharedMesh);
                }
            }

            var asset     = CSGPrefabUtility.GetPrefabAsset(obj);
            var assetPath = AssetDatabase.GetAssetPath(asset);

            var assetObjects = AssetDatabase.LoadAllAssetsAtPath(assetPath);

            foreach (var assetObject in assetObjects)
            {
                var mesh = assetObject as Mesh;
                if (!mesh)
                {
                    continue;
                }
                oldMeshes.Add(mesh);
            }

            if (newMeshes.Count == 0 && oldMeshes.Count == 0)
            {
                return;
            }

            // We might be modifying a prefab, in which case we need to store meshes inside it that belong to it
            AssetDatabase.StartAssetEditing();
            try
            {
                foreach (var oldMesh in oldMeshes)
                {
                    if (newMeshes.Contains(oldMesh))
                    {
                        continue;
                    }

                    if (CanRemoveObjectFromAsset(assetPath, oldMesh, ignoreWhenPartOfOtherAsset: true))
                    {
                        AssetDatabase.RemoveObjectFromAsset(oldMesh);
                    }
                }

                foreach (var _newMesh in newMeshes)
                {
                    var newMesh = _newMesh;
                    if (oldMeshes.Contains(newMesh))
                    {
                        if (IsObjectPartOfAsset(assetPath, newMesh))
                        {
                            continue;
                        }
                    }
                    if (CanAddObjectToAsset(assetPath, newMesh))
                    {
                        AssetDatabase.AddObjectToAsset(newMesh, asset);
                    }
                }
            }
            finally
            {
                AssetDatabase.StopAssetEditing();
            }
        }