Example #1
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();
                }
            }
        }
Example #2
0
        public static bool NeedsRigidBody(CSGModel model)
        {
            var collidable       = (model.Settings & ModelSettingsFlags.NoCollider) != ModelSettingsFlags.NoCollider;
            var isTrigger        = collidable && (model.Settings & ModelSettingsFlags.IsTrigger) == ModelSettingsFlags.IsTrigger;
            var ownerStaticFlags = GameObjectUtility.GetStaticEditorFlags(model.gameObject);
            var batchingstatic   = (ownerStaticFlags & StaticEditorFlags.BatchingStatic) == StaticEditorFlags.BatchingStatic;

            return((batchingstatic || collidable) && !isTrigger);
        }
Example #3
0
 public static bool IsDefaultModel(CSGModel model)
 {
     if ((model.hideFlags & MeshInstanceManager.ComponentHideFlags) == MeshInstanceManager.ComponentHideFlags ||
         (model.hideFlags & HideFlags.DontSave) == HideFlags.DontSave ||
         (model.hideFlags & HideFlags.DontSaveInEditor) == HideFlags.DontSaveInEditor)
     {
         return(true);
     }
     return(false);
 }
Example #4
0
 public static bool IsModelSelectable(CSGModel model)
 {
     if (!model || !model.isActiveAndEnabled)
     {
         return(false);
     }
     if (((1 << model.gameObject.layer) & Tools.visibleLayers) == 0)
     {
         return(false);
     }
     return(true);
 }
        static void SetCSGOperationHierarchy(CSGOperation op, CSGOperation parentOp, CSGModel parentModel)
        {
            SetNodeParent(op.ChildData, op.ParentData, parentOp, parentModel);

/*
 *                      if (!operationCache.ChildData.Model)
 *                              return;
 *
 *                      External.SetOperationHierarchy(op.operationNodeID,
 *                                                                                 operationCache.ChildData.modelNodeID,
 *                                                                                 operationCache.ChildData.parentNodeID);*/
        }
        static void SetCSGBrushHierarchy(CSGBrush brush, CSGOperation parentOp, CSGModel parentModel)
        {
            SetNodeParent(brush.ChildData, brush.hierarchyItem, parentOp, parentModel);

/*
 *                      if (!brushCache.childData.Model)
 *                              return;
 *
 *                      External.SetBrushHierarchy(brush.brushNodeID,
 *                                                                         brushCache.childData.modelNodeID,
 *                                                                         brushCache.childData.parentNodeID);*/
        }
Example #7
0
        public static bool NeedsStaticRigidBody(CSGModel model)
        {
            if (!IsModelEditable(model))
            {
                return(false);
            }

            var ownerStaticFlags = GameObjectUtility.GetStaticEditorFlags(model.gameObject);
            var batchingstatic   = (ownerStaticFlags & StaticEditorFlags.BatchingStatic) == StaticEditorFlags.BatchingStatic;

            return(batchingstatic);
        }
Example #8
0
        public static bool NeedsRigidBody(CSGModel model)
        {
            if (!IsModelEditable(model))
            {
                return(false);
            }

            var collidable       = model.HaveCollider;
            var isTrigger        = collidable && model.IsTrigger;
            var ownerStaticFlags = GameObjectUtility.GetStaticEditorFlags(model.gameObject);
            var batchingstatic   = (ownerStaticFlags & StaticEditorFlags.BatchingStatic) == StaticEditorFlags.BatchingStatic;

            return((batchingstatic || collidable) && !isTrigger);
        }
Example #9
0
 public virtual void Reset()
 {
     editMode                     = EditMode.CreatePlane;
     brushPosition                = MathConstants.zeroVector3;
     parentGameObject             = null;
     parentModel                  = null;
     operationGameObject          = null;
     parentTransform              = null;
     generatedGameObjects         = null;
     generatedBrushes             = null;
     undoGroupIndex               = -1;
     forceCurrentCSGOperationType = invalidCSGOperationType;
     currentCSGOperationType      = invalidCSGOperationType;
 }
Example #10
0
        public static bool WillModelRender(CSGModel model)
        {
#if UNITY_2018_3_OR_NEWER
            var currentPrefabStage = UnityEditor.Experimental.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage();
            if (currentPrefabStage != null)
            {
                var prefabRoot = currentPrefabStage.prefabContentsRoot;
                if (prefabRoot.scene != model.gameObject.scene)
                {
                    return(false);
                }
            }
#endif
            // Is our model valid ...?
            if (!model || !model.isActiveAndEnabled)
            {
                return(false);
            }

            // 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);
        }
Example #11
0
        public virtual void Init()
        {
            prevSelection = new List <UnityEngine.Object>(Selection.objects).ToArray();

            Reset();

            shapeIsValid = true;

            isFinished = false;

            originalGridRotation = RealtimeCSG.CSGGrid.ForcedGridRotation;
            originalGridCenter   = RealtimeCSG.CSGGrid.ForcedGridCenter;
            originalForceGrid    = RealtimeCSG.CSGGrid.ForceGrid;

            geometryModel = null;
        }
Example #12
0
        public static bool IsPrefab(CSGModel model)
        {
            if (!model)
            {
                return(false);
            }

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

            if (parent)
            {
                return(true);
            }

            return(false);
        }
Example #13
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();
                }
            }
        }
Example #14
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);
        }
Example #15
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);
        }
        private static bool TryGetMeshInstance(GeneratedMeshes meshContainer, CSGModel model, ModelSettingsFlags modelSettings, GeneratedMeshDescription meshDescription, RenderSurfaceType renderSurfaceType, out GeneratedMeshInstance meshInstance)
        {
            var startGetMeshInstanceTime = EditorApplication.timeSinceStartup;

            meshInstance         = MeshInstanceManager.GetMeshInstance(meshContainer, meshDescription, modelSettings, renderSurfaceType);
            getMeshInstanceTime += EditorApplication.timeSinceStartup - startGetMeshInstanceTime;
            if (meshInstance &&
                meshDescription == meshInstance.MeshDescription &&
                meshInstance.SharedMesh &&
                meshInstance.IsValid())
            {
                return(true);
            }

            meshInstance = null;
            return(true);
        }
Example #17
0
        private static bool UpdateMesh(CSGModel model,
                                       GeneratedMeshDescription meshDescription,
                                       RenderSurfaceType renderSurfaceType,
                                       ref GeneratedMeshContents outputGeneratedMeshContents,
                                       ref bool outputHasGeneratedNormals,
                                       ref Mesh sharedMesh)
        {
            // create our arrays on the C# side with the correct size
            GeneratedMeshContents generatedMesh;
            var startGetModelMeshesTime = EditorApplication.timeSinceStartup;

            {
                generatedMesh = External.GetModelMesh(model.modelNodeID, meshDescription);
                if (generatedMesh == null)
                {
                    return(false);
                }
            }
            getModelMeshesTime += EditorApplication.timeSinceStartup - startGetModelMeshesTime;

            UpdateMesh(generatedMesh,
                       meshDescription,
                       renderSurfaceType,
                       ref outputHasGeneratedNormals,
                       ref sharedMesh);

            /*
             #if UNITY_2018_3_OR_NEWER
             * var modelGameObject = model.gameObject;
             * var prefabStage = UnityEditor.Experimental.SceneManagement.PrefabStageUtility.GetPrefabStage(modelGameObject);
             * if (prefabStage != null && string.IsNullOrEmpty(AssetDatabase.GetAssetPath(sharedMesh)))
             * {
             *      var prefabAssetPath = prefabStage.prefabAssetPath;
             *      if (!string.IsNullOrEmpty(prefabAssetPath))
             *              AssetDatabase.AddObjectToAsset(sharedMesh, prefabAssetPath);
             *      UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(modelGameObject.scene);
             * }
             #endif
             */
            outputGeneratedMeshContents = generatedMesh;
            return(true);
        }
Example #18
0
        public static bool IsEditedInPrefabMode(CSGModel model)
        {
    #if UNITY_2018_3_OR_NEWER && UNITY_EDITOR
            if (!model)
            {
                return(false);
            }

            if (!AreInPrefabMode())
            {
                return(false);
            }

            var currentStageHandle = StageUtility.GetCurrentStageHandle();
            if (currentStageHandle.Contains(model.gameObject))
            {
                return(true);
            }
    #endif
            return(false);
        }
Example #19
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);
        }
        static void FindParentModel(Transform opTransform, out CSGModel parentModel)
        {
            if (!opTransform)
            {
                parentModel = null;
                return;
            }

            var iterator = opTransform.parent;

            while (iterator)
            {
                var currentNodeObj = iterator.GetComponent(TypeConstants.CSGModelType);
                if (currentNodeObj)
                {
                    parentModel = currentNodeObj as CSGModel;
                    return;
                }

                iterator = iterator.parent;
            }
            parentModel = GetDefaultCSGModelForObject(opTransform);
        }
Example #21
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
        }
Example #22
0
        public static RenderSurfaceType GetModelSurfaceType(CSGModel model)
        {
            if (model.IsRenderable)             // if it's renderable then it's already being rendered using a MeshRenderer
            {
                // except if it's a shadow only surface, it has a MeshRenderer, but is not usually visible ...
//				if (model.ShadowsOnly)
//					return RenderSurfaceType.ShadowOnly;

                return(RenderSurfaceType.Normal);
            }

            if (model.IsTrigger)
            {
                return(RenderSurfaceType.Trigger);
            }

            if (model.HaveCollider)
            {
                return(RenderSurfaceType.Collider);
            }

            return(RenderSurfaceType.Culled);
        }
        public static bool WillModelRender(CSGModel model)
        {
            // Is our model valid ...?
            if (!model || !model.isActiveAndEnabled)
            {
                return(false);
            }

            // 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);
        }
Example #24
0
		internal override bool CreateControlMeshForBrushIndex(CSGModel parentModel, CSGBrush brush, ShapePolygon polygon, Matrix4x4 localToWorld, float height, out ControlMesh newControlMesh, out Shape newShape)
		{
			var direction = haveForcedDirection ? forcedDirection : buildPlane.normal;
            if (!ShapePolygonUtility.GenerateControlMeshFromVertices(polygon,
																	 localToWorld,
																	 GeometryUtility.RotatePointIntoPlaneSpace(buildPlane, direction),
																	 height,
																	
																	 new TexGen(),
																			   
																	 false, 
																	 true,
																	 out newControlMesh,
																	 out newShape))
			{
				return false;
			}
						
			brush.Shape = newShape;
			brush.ControlMesh = newControlMesh;
			InternalCSGModelManager.ValidateBrush(brush, true);
			ControlMeshUtility.RebuildShape(brush);
			return true;
		}
        public static GameObject[] GetModelMeshes(CSGModel model)
        {
            var meshContainer = model.generatedMeshes;
            var meshInstances = MeshInstanceManager.GetAllModelMeshInstances(meshContainer);

            if (meshInstances == null)
            {
                return(new GameObject[0]);
            }

            var gameObjects = new List <GameObject>();

            for (var i = 0; i < meshInstances.Length; i++)
            {
                if (!meshInstances[i] ||
                    meshInstances[i].RenderSurfaceType != RenderSurfaceType.Normal)
                {
                    continue;
                }
                gameObjects.Add(meshInstances[i].gameObject);
            }

            return(gameObjects.ToArray());
        }
Example #26
0
		private bool GenerateSphere(float radius, int splits, CSGModel parentModel, CSGBrush brush, out ControlMesh controlMesh, out Shape shape)
        {
			if (prevSplits != splits || prevIsHemisphere != IsHemiSphere || splitControlMesh == null || splitShape == null)
			{
				splitControlMesh = null;
				splitShape = null;
				BrushFactory.CreateCubeControlMesh(out splitControlMesh, out splitShape, Vector3.one);

				var axi = new Vector3[] { MathConstants.upVector3, MathConstants.leftVector3, MathConstants.forwardVector3 };
				List<int> intersectedEdges = new List<int>();
				float step = 1.0f / (float)(splits + 1);
				float offset;
				for (int i = 0; i < axi.Length; i++)
				{
					var normal = axi[i];
					offset = 0.5f - step;
					while (offset > 0.0f)
					{
						ControlMeshUtility.CutMesh(splitControlMesh, splitShape, new CSGPlane(-normal, -offset), ref intersectedEdges);
						if (i != 0 || !IsHemiSphere)
						{
							ControlMeshUtility.CutMesh(splitControlMesh, splitShape, new CSGPlane(normal, -offset), ref intersectedEdges);
						}
						offset -= step;
					}
					if (i != 0 || !IsHemiSphere)
					{
						if ((splits & 1) == 1)
							ControlMeshUtility.CutMesh(splitControlMesh, splitShape, new CSGPlane(normal, 0), ref intersectedEdges);
					}
				}

				if (IsHemiSphere)
				{
					var cuttingPlane = new CSGPlane(MathConstants.upVector3, 0);
					intersectedEdges.Clear();
					if (ControlMeshUtility.CutMesh(splitControlMesh, splitShape, cuttingPlane, ref intersectedEdges))
					{
						var edge_loop = ControlMeshUtility.FindEdgeLoop(splitControlMesh, ref intersectedEdges);
						if (edge_loop != null)
						{
							if (ControlMeshUtility.SplitEdgeLoop(splitControlMesh, splitShape, edge_loop))
							{
								Shape foundShape;
								ControlMesh foundControlMesh;
								ControlMeshUtility.FindAndDetachSeparatePiece(splitControlMesh, splitShape, cuttingPlane, out foundControlMesh, out foundShape);
							}
						}
					}
				}


				// Spherize the cube
				for (int i = 0; i < splitControlMesh.Vertices.Length; i++)
				{
					Vector3 v = splitControlMesh.Vertices[i] * 2.0f;
					float x2 = v.x * v.x;
					float y2 = v.y * v.y;
					float z2 = v.z * v.z;
					Vector3 s;
					s.x = v.x * Mathf.Sqrt(1f - (y2 * 0.5f) - (z2 * 0.5f) + ((y2 * z2) / 3.0f));
					s.y = v.y * Mathf.Sqrt(1f - (z2 * 0.5f) - (x2 * 0.5f) + ((z2 * x2) / 3.0f));
					s.z = v.z * Mathf.Sqrt(1f - (x2 * 0.5f) - (y2 * 0.5f) + ((x2 * y2) / 3.0f));
					splitControlMesh.Vertices[i] = s;//(splitControlMesh.Vertices[i] * 0.75f) + (splitControlMesh.Vertices[i].normalized * 0.25f);
				}


				if (!ControlMeshUtility.Triangulate(null, splitControlMesh, splitShape))
				{
					Debug.LogWarning("!ControlMeshUtility.IsConvex");
					controlMesh = null;
					shape = null;
					return false;
				}
				ControlMeshUtility.FixTexGens(splitControlMesh, splitShape);

				if (!ControlMeshUtility.IsConvex(splitControlMesh, splitShape))
				{
					Debug.LogWarning("!ControlMeshUtility.IsConvex");
					controlMesh = null;
					shape = null;
					return false;
				}
				ControlMeshUtility.UpdateTangents(splitControlMesh, splitShape);

				prevSplits = splits;
				prevIsHemisphere = IsHemiSphere;
			}

			if (splitControlMesh == null || splitShape == null || !splitControlMesh.Valid)
			{
				Debug.LogWarning("splitControlMesh == null || splitShape == null || !splitControlMesh.IsValid");
				controlMesh = null;
				shape = null;
				return false;
			}

			controlMesh = splitControlMesh.Clone();
			shape = splitShape.Clone();

			/*
			float angle_offset = GeometryUtility.SignedAngle(gridTangent, delta / sphereRadius, buildPlane.normal);
			angle_offset -= 90;

			angle_offset += sphereOffset;
			angle_offset *= Mathf.Deg2Rad;

			Vector3 p1 = MathConstants.zeroVector3;
			for (int i = 0; i < realSplits; i++)
			{
				var angle = ((i * Mathf.PI * 2.0f) / (float)realSplits) + angle_offset;

				p1.x = (Mathf.Sin(angle) * sphereRadius);
				p1.z = (Mathf.Cos(angle) * sphereRadius);
			}
			*/

			for (int i = 0; i < controlMesh.Vertices.Length; i++)
			{
				var vertex = controlMesh.Vertices[i];
				vertex *= radius;
				controlMesh.Vertices[i] = vertex;
			}

			for (int i = 0; i < shape.Surfaces.Length; i++)
			{
				var plane = shape.Surfaces[i].Plane;
				plane.d *= radius;
				shape.Surfaces[i].Plane = plane;
			}

			bool smoothShading = SphereSmoothShading;
			if (!sphereSmoothingGroup.HasValue && smoothShading)
			{
				sphereSmoothingGroup = SurfaceUtility.FindUnusedSmoothingGroupIndex();
			}

			for (int i = 0; i < shape.TexGenFlags.Length; i++)
			{
				shape.TexGens[i].SmoothingGroup = smoothShading ? sphereSmoothingGroup.Value : 0;
			}

			var defaultTexGen = new TexGen();
			defaultTexGen.Scale = MathConstants.oneVector3;
			//defaultTexGen.Color = Color.white;
			
			var fakeSurface = new Surface();
			fakeSurface.TexGenIndex = 0;
			
			var defaultMaterial = CSGSettings.DefaultMaterial;
			for (var s = 0; s < shape.Surfaces.Length; s++)
			{
				var texGenIndex = shape.Surfaces[s].TexGenIndex;

				var axis		= GeometryUtility.SnapToClosestAxis(shape.Surfaces[s].Plane.normal);
				var rotation	= Quaternion.FromToRotation(axis, MathConstants.backVector3);
				var matrix		= Matrix4x4.TRS(MathConstants.zeroVector3, rotation, MathConstants.oneVector3);

				SurfaceUtility.AlignTextureSpaces(matrix, false, ref shape.TexGens[texGenIndex], ref shape.TexGenFlags[texGenIndex], ref shape.Surfaces[s]);
				shape.TexGens[texGenIndex].RenderMaterial = defaultMaterial;
			}

			return true;
        }
 internal abstract bool CreateControlMeshForBrushIndex(CSGModel parentModel, CSGBrush brush, ShapePolygon polygon, Matrix4x4 localToWorld, float height, out ControlMesh newControlMesh, out Shape newShape);
Example #28
0
        protected bool GenerateBrushObjects(int brushObjectCount, bool inGridSpace = true)
        {
            Undo.IncrementCurrentGroup();
            undoGroupIndex = Undo.GetCurrentGroup();

            var lastUsedModel = SelectionUtility.LastUsedModel;

            if (!ModelTraits.IsModelEditable(lastUsedModel))
            {
                lastUsedModel = null;
            }
            var lastUsedModelTransform = !lastUsedModel ? null : lastUsedModel.transform;

            if (!lastUsedModelTransform ||
                !lastUsedModel.isActiveAndEnabled)
            {
                if (prevSelection != null && prevSelection.Length > 0)
                {
                    for (int i = 0; i < prevSelection.Length; i++)
                    {
                        UnityEngine.Object obj   = prevSelection[i];
                        CSGBrush           brush = obj as CSGBrush;
                        MonoBehaviour      mono  = obj as MonoBehaviour;
                        GameObject         go    = obj as GameObject;
                        if (!brush)
                        {
                            if (mono)
                            {
                                brush = mono.GetComponentInChildren <CSGBrush>();
                            }
                            if (go)
                            {
                                brush = go.GetComponentInChildren <CSGBrush>();
                            }
                        }

                        if (!brush)
                        {
                            continue;
                        }

                        if ((brush.gameObject.hideFlags & (HideFlags.HideInHierarchy | HideFlags.NotEditable | HideFlags.DontSaveInBuild)) != 0)
                        {
                            continue;
                        }

                        if (brush.ChildData == null ||
                            brush.ChildData.ModelTransform == null)
                        {
                            continue;
                        }

                        var model = brush.ChildData.Model;
                        if (!model ||
                            !model.isActiveAndEnabled)
                        {
                            continue;
                        }

                        lastUsedModelTransform = brush.ChildData.ModelTransform;
                        break;
                    }
                }
            }

            if (generatedBrushes != null && generatedBrushes.Length > 0)
            {
                for (int i = generatedBrushes.Length - 1; i >= 0; i--)
                {
                    if (generatedBrushes[i])
                    {
                        continue;
                    }
                    ArrayUtility.RemoveAt(ref generatedBrushes, i);
                }
                for (int i = generatedGameObjects.Length - 1; i >= 0; i--)
                {
                    if (generatedGameObjects[i])
                    {
                        var brush = generatedGameObjects[i].GetComponentInChildren <CSGBrush>();
                        if (brush && ArrayUtility.Contains(generatedBrushes, brush))
                        {
                            continue;
                        }
                    }
                    ArrayUtility.RemoveAt(ref generatedGameObjects, i);
                }
            }

            if (generatedGameObjects == null ||
                generatedGameObjects.Length != brushObjectCount)
            {
                if (generatedBrushes != null && generatedBrushes.Length > 0)
                {
                    for (int i = 0; i < generatedBrushes.Length; i++)
                    {
                        InternalCSGModelManager.OnDestroyed(generatedBrushes[i]);
                        GameObject.DestroyImmediate(generatedBrushes[i]);
                    }
                }
                if (generatedGameObjects != null && generatedGameObjects.Length > 0)
                {
                    for (int i = 0; i < generatedGameObjects.Length; i++)
                    {
                        GameObject.DestroyImmediate(generatedGameObjects[i]);
                    }
                }

                if (parentGameObject != null)
                {
                    GameObject.DestroyImmediate(parentGameObject);
                }

                //DebugEditorWindow.PrintDebugInfo();

                if (lastUsedModelTransform == null)
                {
                    parentGameObject = OperationsUtility.CreateGameObject(lastUsedModelTransform, "Model", true);
                    InternalCSGModelManager.CreateCSGModel(parentGameObject);
                    parentModel = parentGameObject.GetComponent <CSGModel>();
                    Undo.RegisterCreatedObjectUndo(parentGameObject, "Created model");

                    if (brushObjectCount > 1)
                    {
                        operationGameObject = OperationsUtility.CreateGameObject(parentGameObject.transform, "Operation", true);
                        var transform = operationGameObject.transform;
                        SetBrushTransformation(transform);

                        var operation = operationGameObject.AddComponent <CSGOperation>();
                        if (CurrentCSGOperationType != invalidCSGOperationType)
                        {
                            operation.OperationType = CurrentCSGOperationType;
                        }
                        operation.HandleAsOne = true;
                        Undo.RegisterCreatedObjectUndo(operationGameObject, "Created operation");
                        parentTransform = operationGameObject.transform;
                    }
                    else
                    {
                        parentTransform = parentGameObject.transform;
                    }
                }
                else
                if (brushObjectCount > 1)
                {
                    parentModel      = lastUsedModelTransform.GetComponent <CSGModel>();
                    parentGameObject = OperationsUtility.CreateGameObject(lastUsedModelTransform, "Brushes", true);
                    var transform = parentGameObject.transform;
                    SetBrushTransformation(transform);

                    operationGameObject = parentGameObject;
                    var operation = operationGameObject.AddComponent <CSGOperation>();
                    if (CurrentCSGOperationType != invalidCSGOperationType)
                    {
                        operation.OperationType = CurrentCSGOperationType;
                    }
                    operation.HandleAsOne = true;
                    parentTransform       = operationGameObject.transform;
                    Undo.RegisterCreatedObjectUndo(parentGameObject, "Created brush");
                }
                else
                {
                    parentGameObject    = null;
                    operationGameObject = null;
                    parentTransform     = lastUsedModelTransform;
                    parentModel         = lastUsedModelTransform.GetComponent <CSGModel>();
                }


                generatedGameObjects = new GameObject[brushObjectCount];
                generatedBrushes     = new CSGBrush[brushObjectCount];
                for (int p = 0; p < brushObjectCount; p++)
                {
                    string name;
                    if (brushObjectCount == 1)
                    {
                        name = "Brush";
                    }
                    else
                    {
                        name = "Brush (" + p + ")";
                    }
                    var gameObject = OperationsUtility.CreateGameObject(parentTransform, name, false);
                    gameObject.SetActive(false);

                    var brushComponent = gameObject.AddComponent <CSGBrush>();

                    if (operationGameObject == null)
                    {
                        if (CurrentCSGOperationType != invalidCSGOperationType)
                        {
                            brushComponent.OperationType = CurrentCSGOperationType;
                        }
                        operationGameObject = gameObject;
                        var transform = gameObject.transform;
                        SetBrushTransformation(transform);
                    }

                    generatedBrushes[p]             = brushComponent;
                    generatedBrushes[p].ControlMesh = new ControlMesh();
                    generatedBrushes[p].Shape       = new Shape();
                    Undo.RegisterCreatedObjectUndo(gameObject, "Created brush");
                    generatedGameObjects[p] = gameObject;
                }
                //InternalCSGModelManager.Refresh(forceHierarchyUpdate: true);
                // brushes not registered at this point!??


                //DebugEditorWindow.PrintDebugInfo();
                //Selection.objects = generatedGameObjects;
            }
            else
            {
                UpdateBrushPosition();
            }

            return(generatedBrushes != null && generatedBrushes.Length > 0 && generatedBrushes.Length == brushObjectCount);
        }
Example #29
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);
            }
        }
        static void SetNodeParent(ChildNodeData childData, HierarchyItem hierarchyItem, CSGOperation parentOp, CSGModel parentModel)
        {
            var oldParentData = childData.OwnerParentData;

            childData.Parent = parentOp;
            childData.Model  = parentModel;
            var newParentData = GetParentData(childData);

            if (oldParentData != newParentData)
            {
                if (oldParentData != null)
                {
                    oldParentData.RemoveNode(hierarchyItem);
                }
                if (newParentData != null)
                {
                    newParentData.AddNode(hierarchyItem);
                }
                childData.OwnerParentData = newParentData;
                childData.ModelTransform  = (!childData.Model) ? null : childData.Model.transform;
            }
        }