示例#1
0
        public static void GenerateFromSurface(CSGBrush cSGBrush, CSGPlane polygonPlane, Vector3 direction, Vector3[] points, int[] pointIndices, uint[] smoothingGroups, bool drag)
        {
            EditModeManager.EditMode = ToolEditMode.Generate;
            UpdateTool();
            var generateBrushTool = brushTools[(int)ToolEditMode.Generate] as EditModeGenerate;

            generateBrushTool.GenerateFromPolygon(cSGBrush, polygonPlane, direction, points, pointIndices, smoothingGroups, drag);
        }
示例#2
0
        public static void GenerateFromSurface(Camera camera, CSGBrush cSGBrush, CSGPlane polygonPlane, Vector3 direction, Vector3[] points, int[] pointIndices, uint[] smoothingGroups, bool drag, CSGOperationType forceDragSource, bool autoCommitExtrusion)
        {
            EditModeManager.EditMode = ToolEditMode.Generate;
            UpdateTool();
            var generateBrushTool = brushTools[(int)ToolEditMode.Generate] as EditModeGenerate;

            generateBrushTool.GenerateFromPolygon(camera, cSGBrush, polygonPlane, direction, points, pointIndices, smoothingGroups, drag, forceDragSource, autoCommitExtrusion);
        }
示例#3
0
		public static bool IsSurfaceUnselectable(CSGBrush brush, int surfaceIndex, bool isTrigger, bool ignoreSurfaceFlags = false)
		{
			if (!brush)
			{
				return true;
			}

			var shape = brush.Shape;
			if (shape == null)
			{
				return true;
			}

			var surfaces = shape.Surfaces;
			if (surfaces == null)
			{
				return true;
			}

			if (surfaceIndex < 0 || surfaceIndex >= surfaces.Length)
			{
				return true;
			}

			var texGenIndex = surfaces[surfaceIndex].TexGenIndex;
			var texGenFlags = shape.TexGenFlags;
			if (texGenFlags == null ||
				texGenIndex < 0 || texGenIndex >= texGenFlags.Length)
			{
				return true;
			}

			if (ignoreSurfaceFlags)
			{
				var isNotRenderable = (texGenFlags[texGenIndex] & TexGenFlags.NoRender) == TexGenFlags.NoRender;
				if (!isNotRenderable)
					return false;

				if (isNotRenderable && CSGSettings.ShowHiddenSurfaces)
					return false;

				var isCollidable = (texGenFlags[texGenIndex] & TexGenFlags.NoCollision) != TexGenFlags.NoCollision;
				if (isCollidable)
				{
					if (isTrigger)
					{
						if (CSGSettings.ShowTriggerSurfaces)
							return false;
					} else
					{
						if (CSGSettings.ShowColliderSurfaces)
							return false;
					}
				}
				return true;
			}			
			return false;
		}
示例#4
0
 public override void Reset()
 {
     settings.Reset();
     base.Reset();
     hoverDefaultPlane  = null;
     firstSnappedPlanes = null;
     firstSnappedEdges  = null;
     firstSnappedBrush  = null;
 }
 public void Reset()
 {
     childData.Reset();
     hierarchyItem.Reset();
     brush = null;
     //TriangulatedMesh = null;
     //ControlShape = null;
     compareShape.Reset();
 }
示例#6
0
        public static Color GetBrushOutlineColor(CSGBrush brush)
        {
            if (outlines2D == null)
            {
                Update();
            }
            var instanceID = Mathf.Abs(brush.GetInstanceID());

            return(outlines2D[instanceID % outlines2D.Length]);
        }
        public void UpdateLayout(CSGBrush brush)
        {
            var shape        = brush.Shape;
            int surfaceCount = shape.Surfaces.Length;

            if (surfaceControlID.Length != surfaceCount)
            {
                AllocateSurfaces(surfaceCount);
            }
        }
        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);*/
        }
示例#9
0
        public static void SetPivotToLocalCenter(CSGBrush brush)
        {
            if (!brush)
            {
                return;
            }

            var localCenter = BoundsUtilities.GetLocalCenter(brush);
            var worldCenter = brush.transform.localToWorldMatrix.MultiplyPoint(localCenter);

            SetPivot(brush, worldCenter);
        }
示例#10
0
        public SelectedBrushSurface[] HoverOnBrush(CSGBrush hoverBrush, int surfaceIndex)
        {
            if (!hoverBrush)
            {
                return(null);
            }

            return(new SelectedBrushSurface[]
            {
                new SelectedBrushSurface(hoverBrush, surfaceIndex)
            });
        }
示例#11
0
        public static bool IsSurfaceSelectable(CSGBrush brush, int surfaceIndex)
        {
            if (!brush)
            {
                //Debug.Log("!brush");
                return(true);
            }

            var shape = brush.Shape;

            if (shape == null)
            {
                //Debug.Log("shape == null");
                return(true);
            }

            var surfaces = shape.Surfaces;

            if (surfaces == null)
            {
                //Debug.Log("surfaces == null");
                return(true);
            }

            if (surfaceIndex < 0 || surfaceIndex >= surfaces.Length)
            {
                //Debug.Log("surfaceIndex("+surfaceIndex+") < 0 || surfaceIndex >= surfaces.Length("+surfaces.Length+")");
                return(true);
            }

            var texGenIndex = surfaces[surfaceIndex].TexGenIndex;
            var texGenFlags = shape.TexGenFlags;

            if (texGenFlags == null ||
                texGenIndex < 0 || texGenIndex >= texGenFlags.Length)
            {
                return(true);
            }

            if ((texGenFlags[texGenIndex] & TexGenFlags.NoRender) == TexGenFlags.NoRender)
            {
                return(!CSGSettings.ShowHiddenSurfaces);
            }

            if ((texGenFlags[texGenIndex] & TexGenFlags.NoCastShadows) == TexGenFlags.NoCastShadows)
            {
                return(!CSGSettings.ShowCastShadowsSurfaces);
            }

            return(false);
        }
示例#12
0
		public override void Reset() 
		{
            settings.Reset();
			base.Reset();
			firstSnappedPlanes	= null;
			firstSnappedEdges	= null;
			firstSnappedBrush	= null;
			hadSphere = false;		
			prevSplits = -1;
			prevIsHemisphere = IsHemiSphere;
			splitControlMesh = null;
			splitShape = null;
			sphereSmoothingGroup = null;
		}
        static void CheckBrushHierarchy(CSGBrush brush)
        {
            if (External == null)
            {
                return;
            }

            if (!brush || !brush.gameObject.activeInHierarchy)
            {
                if (!brush && brush.IsRegistered)
                {
                    OnDestroyed(brush);
                }
                return;
            }

            // make sure the node has already been initialized,
            // otherwise ignore it
            if (!brush.IsRegistered)
            {
                return;
            }

            if (RemovedBrushes.Contains(brush.brushNodeID))
            {
                return;
            }

            // NOTE: returns default model when it can't find parent model
            CSGModel     parentModel;
            CSGOperation parentOp;

            FindParentOperationAndModel(brush.transform, out parentOp, out parentModel);

            if (brush.ChildData.Parent == parentOp &&
                brush.ChildData.Model == parentModel)
            {
                if (parentOp)
                {
                    ParentNodeDataExtensions.UpdateNodePosition(brush.hierarchyItem, parentOp.ParentData);
                    return;
                }
            }

            SetCSGBrushHierarchy(brush, parentOp, parentModel);
        }
示例#14
0
        public static void SetPivot(CSGBrush brush, Vector3 newCenter)
        {
            if (!brush)
            {
                return;
            }

            var transform  = brush.transform;
            var realCenter = transform.position;
            var difference = newCenter - realCenter;

            if (difference.sqrMagnitude < MathConstants.ConsideredZero)
            {
                return;
            }

            transform.position += difference;

            GeometryUtility.MoveControlMeshVertices(brush, -difference);
            SurfaceUtility.TranslateSurfacesInWorldSpace(brush, -difference);
            ControlMeshUtility.RebuildShape(brush);
        }
示例#15
0
        public static void DrawPolygonCenters(LineMeshManager lineManager, CSGBrush brush)
        {
            // todo: check perf and maybe have to cache this somewhere
            var controlState = new ControlMeshState(brush);

            controlState.UpdatePoints(brush.ControlMesh);

            for (int i = 0; i < controlState.PolygonCenterPoints.Length; i++)
            {
                var normal = brush.compareTransformation.localToWorldMatrix.MultiplyVector(controlState.PolygonCenterPlanes[i].normal);
                var pa     = controlState.PolygonCenterPoints[i] + normal * .002f;
                var move   = 2 * .0254f;

                var t1       = Vector3.Cross(normal, Vector3.forward);
                var t2       = Vector3.Cross(normal, Vector3.up);
                var tangent  = t1.magnitude > t2.magnitude ? t1 : t2;
                var tangent2 = Quaternion.AngleAxis(90, normal) * tangent;

                lineManager.DrawLine(pa - tangent * move, pa + tangent * move, ColorSettings.HelperPolygonCenter);
                lineManager.DrawLine(pa - tangent2 * move, pa + tangent2 * move, ColorSettings.HelperPolygonCenter);
            }
        }
示例#16
0
        public static void MoveControlMeshVertices(CSGBrush brush, Vector3 offset)
        {
            if (!brush)
            {
                return;
            }

            var controlMesh = brush.ControlMesh;

            if (controlMesh == null ||
                controlMesh.Vertices == null)
            {
                return;
            }

            var localOffset = brush.transform.worldToLocalMatrix.MultiplyVector(offset);

            for (var p = 0; p < controlMesh.Vertices.Length; p++)
            {
                controlMesh.Vertices[p] = controlMesh.Vertices[p] + localOffset;
            }
        }
示例#17
0
        public static bool SetBrushCubeMesh(CSGBrush brush, Vector3 size)
        {
            if (!brush)
            {
                return(false);
            }

            ControlMesh controlMesh;
            Shape       shape;

            BrushFactory.CreateCubeControlMesh(out controlMesh, out shape, size);

            brush.ControlMesh = controlMesh;
            brush.Shape       = shape;
            if (brush.ControlMesh != null)
            {
                brush.ControlMesh.SetDirty();
            }
            if (brush.Shape != null)
            {
                ShapeUtility.EnsureInitialized(brush.Shape);
            }
            return(true);
        }
示例#18
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;
		}
 internal abstract bool CreateControlMeshForBrushIndex(CSGModel parentModel, CSGBrush brush, ShapePolygon polygon, Matrix4x4 localToWorld, float height, out ControlMesh newControlMesh, out Shape newShape);
示例#20
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;
        }
示例#21
0
 protected void ResetVisuals()
 {
     visualSnappedEdges = null;
     visualSnappedGrid  = null;
     visualSnappedBrush = null;
 }
示例#22
0
		protected override void HandleCreateShapeEvents(SceneView sceneView, Rect sceneRect)
		{
			bool		pointOnEdge			= false;
			bool		havePlane			= false;
			bool		vertexOnGeometry	= false;
			CSGBrush	vertexOnBrush		= null;
			
			CSGPlane	hoverBuildPlane		= buildPlane;
            var camera = sceneView.camera;
            var assume2DView = CSGSettings.Assume2DView(camera);
			if (camera != null &&
				camera.pixelRect.Contains(Event.current.mousePosition))
			{
				if (!hoverDefaultPlane.HasValue ||
					settings.vertices.Length == 0)
				{
					bool forceGrid = RealtimeCSG.CSGGrid.ForceGrid;
					RealtimeCSG.CSGGrid.ForceGrid = false;
					hoverDefaultPlane = RealtimeCSG.CSGGrid.CurrentGridPlane;
					RealtimeCSG.CSGGrid.ForceGrid = forceGrid;
					firstSnappedEdges = null;
					firstSnappedBrush = null;
					firstSnappedPlanes = null;
					base.geometryModel = null;
				}
				if (editMode == EditMode.CreatePlane)
				{
					LegacyBrushIntersection intersection;
					if (!assume2DView && !havePlane &&
                        EditorWindow.mouseOverWindow == sceneView &&
                        SceneQueryUtility.FindWorldIntersection(camera, Event.current.mousePosition, out intersection))
					{
						worldPosition = intersection.worldIntersection;
						hoverBuildPlane = intersection.worldPlane;
						vertexOnBrush = intersection.brush;

						vertexOnGeometry = true;
					} else
					{
						hoverBuildPlane = hoverDefaultPlane.Value;
						vertexOnBrush = null;

						var mouseRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
						worldPosition = hoverBuildPlane.RayIntersection(mouseRay);
						vertexOnGeometry = false;
					}
					
					ResetVisuals();
					if (snapFunction != null)
					{
						CSGBrush snappedOnBrush;
						worldPosition = snapFunction(camera, worldPosition, hoverBuildPlane, ref visualSnappedEdges, out snappedOnBrush, generatedBrushes, ignoreAllBrushes: true);
						if (snappedOnBrush != null)
						{
							pointOnEdge = (visualSnappedEdges != null &&
									  visualSnappedEdges.Count > 0);
							vertexOnBrush = snappedOnBrush;
							vertexOnGeometry = true;
						}
					}

					if (settings.vertices.Length == 1)
					{
						if (hoverBuildPlane.normal != MathConstants.zeroVector3)
						{
							editMode = EditMode.CreateShape;
							havePlane = true;
						}
					}
				} else
				{
					var mouseRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
					worldPosition = hoverBuildPlane.RayIntersection(mouseRay);

					ResetVisuals();
					if (snapFunction != null)
					{
						CSGBrush snappedOnBrush;
						worldPosition = snapFunction(camera, worldPosition, hoverBuildPlane, ref visualSnappedEdges, out snappedOnBrush, generatedBrushes, ignoreAllBrushes: true);
						if (snappedOnBrush != null)
						{
							pointOnEdge = (visualSnappedEdges != null &&
											visualSnappedEdges.Count > 0);
							vertexOnBrush = snappedOnBrush;
						}
					}
				}

				if (geometryModel == null && vertexOnBrush != null)
				{
					if (vertexOnBrush.ChildData != null && vertexOnBrush.ChildData.Model)
						geometryModel = vertexOnBrush.ChildData.Model;
				}

				if (worldPosition != prevWorldPosition)
				{
					prevWorldPosition = worldPosition;
					if (settings.vertices.Length > 0)
					{
						if (hadSphere || (settings.vertices[0] - worldPosition).sqrMagnitude > MathConstants.EqualityEpsilon)
						{
							hadSphere = true;
							UpdateBaseShape(true);
						}
					}
					if (Event.current.type != EventType.Repaint)
						CSG_EditorGUIUtility.RepaintAll();
				}
				
				visualSnappedGrid = RealtimeCSG.CSGGrid.FindAllGridEdgesThatTouchPoint(camera, worldPosition);
				visualSnappedBrush = vertexOnBrush;
			}
			
			RealtimeCSG.CSGGrid.SetForcedGrid(camera, hoverBuildPlane);
			

			if (!SceneDragToolManager.IsDraggingObjectInScene &&
				Event.current.type == EventType.Repaint)
			{
				PaintSnapVisualisation();
				PaintCircle(sceneView, base.shapeId);
			}
			

			var type = Event.current.GetTypeForControl(base.shapeId);
			switch (type)
			{
				case EventType.Layout:
				{
					return;
				}

				case EventType.ValidateCommand:
				case EventType.KeyDown:
				{
					if (GUIUtility.hotControl == base.shapeId)
					{
						if (Keys.PerformActionKey.IsKeyPressed() ||
							Keys.DeleteSelectionKey.IsKeyPressed() ||
							Keys.CancelActionKey.IsKeyPressed())
						{
							Event.current.Use();
						}
					}
					return;
				}
				case EventType.KeyUp:
				{
					if (GUIUtility.hotControl == base.shapeId)
					{
						if (Keys.CylinderBuilderMode.IsKeyPressed() ||
							Keys.PerformActionKey.IsKeyPressed())
						{
							HotKeyReleased(); 
							Event.current.Use();
							return;
						}
						if (Keys.DeleteSelectionKey.IsKeyPressed() ||
							Keys.CancelActionKey.IsKeyPressed())
						{
							Cancel();
							Event.current.Use();
							return;
						}
					}
					return;
				}

				case EventType.MouseDown:
				{
					if (!sceneRect.Contains(Event.current.mousePosition))
						break;
					if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
						return;
					if ((GUIUtility.hotControl != 0 && GUIUtility.hotControl != shapeEditId && GUIUtility.hotControl != base.shapeId) ||
						Event.current.button != 0)
						return;
					
					Event.current.Use();
					if (settings.vertices.Length == 0)
					{
						if ((GUIUtility.hotControl == 0 ||
							GUIUtility.hotControl == base.shapeEditId) && base.shapeId != -1)
                        {
							base.CalculateWorldSpaceTangents(camera);
                            GUIUtility.hotControl = base.shapeId;
							GUIUtility.keyboardControl = base.shapeId;
							EditorGUIUtility.editingTextField = false; 
						}
					}

					if (GUIUtility.hotControl == base.shapeId && settings.vertices.Length < 2)
					{
						if (!float.IsNaN(worldPosition.x) && !float.IsInfinity(worldPosition.x) &&
							!float.IsNaN(worldPosition.y) && !float.IsInfinity(worldPosition.y) &&
							!float.IsNaN(worldPosition.z) && !float.IsInfinity(worldPosition.z))
						{
							if (hoverBuildPlane.normal.sqrMagnitude != 0)
								buildPlane = hoverBuildPlane;
							CalculateWorldSpaceTangents(camera);

							if (settings.vertices.Length == 0)
							{
								if (pointOnEdge)
								{
									firstSnappedEdges = visualSnappedEdges.ToArray();
									firstSnappedBrush = visualSnappedBrush;
									firstSnappedPlanes = null;
								} else
								{
									firstSnappedBrush = null;
									firstSnappedEdges = null;
									firstSnappedPlanes = null;
								}
								planeOnGeometry = vertexOnGeometry;
							} else
							{
								if (firstSnappedEdges != null)
								{
									if (firstSnappedPlanes == null)
										CreateSnappedPlanes();

									bool outside = true;
									for (int i = 0; i < firstSnappedPlanes.Length; i++)
									{
										if (firstSnappedPlanes[i].Distance(worldPosition) <= MathConstants.DistanceEpsilon)
										{
											outside = false;
											break;
										}
									}

									planeOnGeometry = !outside;
								}

								if (vertexOnGeometry)
								{
									var plane = hoverDefaultPlane.Value;
									var distance = plane.Distance(worldPosition);
									plane.d += distance;
									hoverDefaultPlane = plane;

									for (int i = 0; i < settings.vertices.Length; i++)
									{
										if (!settings.onGeometryVertices[i])
										{
											settings.vertices[i] = GeometryUtility.ProjectPointOnPlane(plane, settings.vertices[i]);
											settings.onGeometryVertices[i] = true;
										}
									}
								}
							}
							ArrayUtility.Add(ref settings.onGeometryVertices, vertexOnGeometry);
							settings.AddPoint(worldPosition);
							CSG_EditorGUIUtility.RepaintAll();
							if (settings.vertices.Length == 2)
							{
								HotKeyReleased();
							}
						}
					}
					return;
				}
				case EventType.MouseDrag:
				{
					if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
						break;
					if (GUIUtility.hotControl == base.shapeId && Event.current.button == 0)
					{
						Event.current.Use();
					}
					return;
				}
				case EventType.MouseUp:
				{
					if (GUIUtility.hotControl != base.shapeId)
						return;
					if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
						return;
					if (Event.current.button == 0)
					{
						Event.current.Use(); 

						ResetVisuals();
						if (settings.vertices.Length == 2)
						{
							GUIUtility.hotControl = 0;
							GUIUtility.keyboardControl = 0;
							EditorGUIUtility.editingTextField = false;

							editMode = EditMode.CreateShape;
							HotKeyReleased();
						}
					}
					return;
				}
			}
		}
示例#23
0
        public void AddVertex(Vector3 position, CSGBrush brush, CSGPlane plane, bool onGeometry)
        {
            if (curve.Points.Length > 1)
            {
                if ((curve.Points[curve.Points.Length - 1] - position).sqrMagnitude < MathConstants.EqualityEpsilonSqr)
                {
                    return;
                }
                if ((curve.Points[0] - position).sqrMagnitude < MathConstants.EqualityEpsilonSqr)
                {
                    return;
                }
            }

            var leftTangentCurve = new TangentCurve2D()
            {
                Tangent    = MathConstants.leftVector3,
                Constraint = HandleConstraints.Straight
            };

            var rightTangentCurve = new TangentCurve2D()
            {
                Tangent    = MathConstants.rightVector3,
                Constraint = HandleConstraints.Straight
            };

            var handlePointCurve = new HandlePointCurve2D()
            {
                ID    = -1,
                State = SelectState.None
            };

            var leftTangentCurveHandle = new HandleTangentCurve2D()
            {
                ID         = -1,
                State      = SelectState.None,
                Constraint = HandleConstraints.Straight
            };

            var rightTangentCurveHandle = new HandleTangentCurve2D()
            {
                ID         = -1,
                State      = SelectState.None,
                Constraint = HandleConstraints.Straight
            };

            var handleEdgeCurve = new HandleEdgeCurve2D()
            {
                ID     = -1,
                State  = SelectState.None,
                Texgen = new TexGen(CSGSettings.DefaultMaterial)
            };

            ArrayUtility.Add(ref curve.Points, position);
            ArrayUtility.Add(ref curvePointHandles, handlePointCurve);
            ArrayUtility.Add(ref curveEdgeHandles, handleEdgeCurve);

            ArrayUtility.Add(ref curve.Tangents, rightTangentCurve);
            ArrayUtility.Add(ref curve.Tangents, leftTangentCurve);
            ArrayUtility.Add(ref curveTangentHandles, rightTangentCurveHandle);
            ArrayUtility.Add(ref curveTangentHandles, leftTangentCurveHandle);

            ArrayUtility.Add(ref onGeometryVertices, onGeometry);
            //           ArrayUtility.Add(ref onPlaneVertices, plane);
            ArrayUtility.Add(ref onBrushVertices, brush);
        }
示例#24
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);
        }
        public bool DragUpdated(SceneView sceneView)
        {
            var camera = sceneView.camera;
            LegacyBrushIntersection intersection;
            int      highlight_surface = -1;
            CSGBrush highlight_brush   = null;

            if (!SceneQueryUtility.FindWorldIntersection(camera, Event.current.mousePosition, out intersection))
            {
                highlight_brush   = null;
                highlight_surface = -1;
            }
            else
            {
                highlight_brush   = intersection.brush;
                highlight_surface = intersection.surfaceIndex;
            }

            bool modified = true;

            if (hoverBrushSurfaces != null)
            {
                for (int i = 0; i < hoverBrushSurfaces.Length; i++)
                {
                    if (hoverBrushSurfaces[i].brush == highlight_brush &&
                        hoverBrushSurfaces[i].surfaceIndex == highlight_surface)
                    {
                        modified = false;
                        break;
                    }
                }
            }

            bool needUpdate = false;

            if (modified)
            {
                hoverOnSelectedSurfaces = false;
                if (hoverBrushSurfaces != null)
                {
                    needUpdate = true;
                    RestoreMaterials(hoverBrushSurfaces);
                }

                hoverBrushSurfaces = HoverOnBrush(new CSGBrush[1] {
                    highlight_brush
                }, highlight_surface);

                if (hoverBrushSurfaces != null)
                {
                    hoverBrushSurfaces = GetCombinedBrushes(hoverBrushSurfaces);
                    needUpdate         = true;
                    using (new UndoGroup(hoverBrushSurfaces, "Modified materials"))
                    {
                        RememberMaterials(hoverBrushSurfaces);
                        ApplyMaterial(hoverBrushSurfaces);
                    }
                }
            }
            else
            {
                bool prevSelectAllSurfaces = selectAllSurfaces;
                selectAllSurfaces = Event.current.shift;

                if (prevSelectAllSurfaces != selectAllSurfaces)
                {
                    if (hoverBrushSurfaces != null)
                    {
                        needUpdate = true;

                        using (new UndoGroup(hoverBrushSurfaces, "Modified materials"))
                        {
                            ApplyMaterial(hoverBrushSurfaces);
                        }
                    }
                }
            }

            if (needUpdate)
            {
                InternalCSGModelManager.UpdateMeshes();
                MeshInstanceManager.UpdateHelperSurfaceVisibility();
            }
            return(needUpdate);
        }
示例#26
0
        protected override void HandleCreateShapeEvents(Rect sceneRect)
        {
            if (settings.vertices.Length < 2)
            {
                if (editMode == EditMode.ExtrudeShape ||
                    editMode == EditMode.EditShape)
                {
                    editMode = EditMode.CreatePlane;
                }
            }

            bool     pointOnEdge      = false;
            bool     havePlane        = false;
            bool     vertexOnGeometry = false;
            CSGBrush vertexOnBrush    = null;

            CSGPlane hoverBuildPlane = buildPlane;
            var      sceneView       = SceneView.currentDrawingSceneView; //(SceneView.currentDrawingSceneView != null) ? SceneView.currentDrawingSceneView : SceneView.lastActiveSceneView;
            var      camera          = (sceneView == null) ? null : sceneView.camera;

            if (camera != null &&
                camera.pixelRect.Contains(Event.current.mousePosition))
            {
                if (!hoverDefaultPlane.HasValue ||
                    settings.vertices.Length == 0)
                {
                    bool forceGrid = RealtimeCSG.CSGGrid.ForceGrid;
                    RealtimeCSG.CSGGrid.ForceGrid = false;
                    hoverDefaultPlane             = RealtimeCSG.CSGGrid.CurrentGridPlane;
                    RealtimeCSG.CSGGrid.ForceGrid = forceGrid;
                    firstSnappedEdges             = null;
                    firstSnappedBrush             = null;
                    firstSnappedPlanes            = null;
                    base.geometryModel            = null;
                }
                if (editMode == EditMode.CreatePlane)
                {
                    BrushIntersection intersection;
                    if (!IgnoreDepthForRayCasts(sceneView) && !havePlane &&
                        SceneQueryUtility.FindWorldIntersection(Event.current.mousePosition, out intersection))
                    {
                        worldPosition = intersection.worldIntersection;
                        if (intersection.surfaceInverted)
                        {
                            hoverBuildPlane = intersection.plane.Negated();
                        }
                        else
                        {
                            hoverBuildPlane = intersection.plane;
                        }
                        vertexOnBrush = intersection.brush;

                        vertexOnGeometry = true;
                    }
                    else
                    {
                        hoverBuildPlane = hoverDefaultPlane.Value;
                        vertexOnBrush   = null;

                        var mouseRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                        worldPosition    = hoverBuildPlane.Intersection(mouseRay);
                        vertexOnGeometry = false;
                    }

                    ResetVisuals();
                    if (snapFunction != null)
                    {
                        CSGBrush snappedOnBrush;
                        worldPosition = snapFunction(worldPosition, hoverBuildPlane, ref visualSnappedEdges, out snappedOnBrush, generatedBrushes);
                        if (snappedOnBrush != null)
                        {
                            pointOnEdge = (visualSnappedEdges != null &&
                                           visualSnappedEdges.Count > 0);
                            vertexOnBrush    = snappedOnBrush;
                            vertexOnGeometry = true;
                        }
                    }

                    if (settings.vertices.Length == 1)
                    {
                        if (hoverBuildPlane.normal != MathConstants.zeroVector3)
                        {
                            editMode  = EditMode.CreateShape;
                            havePlane = true;
                        }
                    }
                    else
                    if (settings.vertices.Length == 2)
                    {
                        onLastPoint = true;
                    }
                }
                else
                {
                    var mouseRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                    worldPosition = hoverBuildPlane.Intersection(mouseRay);

                    ResetVisuals();
                    if (snapFunction != null)
                    {
                        CSGBrush snappedOnBrush;
                        worldPosition = snapFunction(worldPosition, hoverBuildPlane, ref visualSnappedEdges, out snappedOnBrush, generatedBrushes);
                        if (snappedOnBrush != null)
                        {
                            pointOnEdge = (visualSnappedEdges != null &&
                                           visualSnappedEdges.Count > 0);
                            vertexOnBrush = snappedOnBrush;
                        }
                    }
                }

                if (geometryModel == null && vertexOnBrush != null)
                {
                    var brush_cache = InternalCSGModelManager.GetBrushCache(vertexOnBrush);
                    if (brush_cache != null && brush_cache.childData != null && brush_cache.childData.Model)
                    {
                        geometryModel = brush_cache.childData.Model;
                    }
                }

                if (worldPosition != prevWorldPosition)
                {
                    prevWorldPosition = worldPosition;
                    if (Event.current.type != EventType.Repaint)
                    {
                        SceneView.RepaintAll();
                    }
                }

                visualSnappedGrid  = RealtimeCSG.CSGGrid.FindAllGridEdgesThatTouchPoint(worldPosition);
                visualSnappedBrush = vertexOnBrush;
            }

            RealtimeCSG.CSGGrid.SetForcedGrid(hoverBuildPlane);


            if (!SceneDragToolManager.IsDraggingObjectInScene &&
                Event.current.type == EventType.Repaint)
            {
                PaintSnapVisualisation();
                PaintShape(base.shapeId);
            }


            var type = Event.current.GetTypeForControl(base.shapeId);

            switch (type)
            {
            case EventType.Layout:
            {
                return;
            }

            case EventType.ValidateCommand:
            case EventType.KeyDown:
            {
                if (GUIUtility.hotControl == base.shapeId)
                {
                    if (Keys.PerformActionKey.IsKeyPressed() ||
                        Keys.DeleteSelectionKey.IsKeyPressed() ||
                        Keys.CancelActionKey.IsKeyPressed())
                    {
                        Event.current.Use();
                    }
                }
                return;
            }

            case EventType.KeyUp:
            {
                if (GUIUtility.hotControl == base.shapeId)
                {
                    if (Keys.BoxBuilderMode.IsKeyPressed() ||
                        Keys.PerformActionKey.IsKeyPressed())
                    {
                        HotKeyReleased();
                        Event.current.Use();
                        return;
                    }
                    if (Keys.DeleteSelectionKey.IsKeyPressed() ||
                        Keys.CancelActionKey.IsKeyPressed())
                    {
                        Cancel();
                        Event.current.Use();
                        return;
                    }
                }
                return;
            }

            case EventType.MouseDown:
            {
                if (!sceneRect.Contains(Event.current.mousePosition))
                {
                    break;
                }
                if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
                {
                    return;
                }
                if ((GUIUtility.hotControl != 0 && GUIUtility.hotControl != shapeEditId && GUIUtility.hotControl != base.shapeId) ||
                    Event.current.button != 0)
                {
                    return;
                }

                Event.current.Use();
                if (settings.vertices.Length == 0)
                {
                    if ((GUIUtility.hotControl == 0 ||
                         GUIUtility.hotControl == base.shapeEditId) && base.shapeId != -1)
                    {
                        base.CalculateWorldSpaceTangents();
                        GUIUtility.hotControl             = base.shapeId;
                        GUIUtility.keyboardControl        = base.shapeId;
                        EditorGUIUtility.editingTextField = false;
                    }
                }

                if (GUIUtility.hotControl == base.shapeId && settings.vertices.Length < 2)
                {
                    if (!float.IsNaN(worldPosition.x) && !float.IsInfinity(worldPosition.x) &&
                        !float.IsNaN(worldPosition.y) && !float.IsInfinity(worldPosition.y) &&
                        !float.IsNaN(worldPosition.z) && !float.IsInfinity(worldPosition.z))
                    {
                        if (hoverBuildPlane.normal.sqrMagnitude != 0)
                        {
                            buildPlane = hoverBuildPlane;
                        }
                        CalculateWorldSpaceTangents();

                        if (settings.vertices.Length == 0)
                        {
                            if (pointOnEdge)
                            {
                                firstSnappedEdges  = visualSnappedEdges.ToArray();
                                firstSnappedBrush  = visualSnappedBrush;
                                firstSnappedPlanes = null;
                            }
                            else
                            {
                                firstSnappedBrush  = null;
                                firstSnappedEdges  = null;
                                firstSnappedPlanes = null;
                            }
                            geometryPlane   = buildPlane;
                            planeOnGeometry = vertexOnGeometry;
                        }
                        else
                        {
                            if (firstSnappedEdges != null)
                            {
                                if (firstSnappedPlanes == null)
                                {
                                    CreateSnappedPlanes();
                                }

                                bool outside = true;
                                for (int i = 0; i < firstSnappedPlanes.Length; i++)
                                {
                                    if (firstSnappedPlanes[i].Distance(worldPosition) <= MathConstants.DistanceEpsilon)
                                    {
                                        outside = false;
                                        break;
                                    }
                                }

                                planeOnGeometry = !outside;
                            }

                            if (vertexOnGeometry)
                            {
                                var plane    = hoverDefaultPlane.Value;
                                var distance = plane.Distance(worldPosition);
                                if (float.IsInfinity(distance) || float.IsNaN(distance))
                                {
                                    distance = 1.0f;
                                }
                                plane.d          += distance;
                                hoverDefaultPlane = plane;

                                for (int i = 0; i < settings.vertices.Length; i++)
                                {
                                    if (!settings.onGeometryVertices[i])
                                    {
                                        settings.vertices[i]           = GeometryUtility.ProjectPointOnPlane(plane, settings.vertices[i]);
                                        settings.onGeometryVertices[i] = true;
                                    }
                                }
                            }
                        }
                        ArrayUtility.Add(ref settings.onGeometryVertices, vertexOnGeometry);
                        settings.AddPoint(worldPosition);
                        SceneView.RepaintAll();
                        if (settings.vertices.Length == 2)
                        {
                            HotKeyReleased();
                        }
                    }
                }
                return;
            }

            case EventType.MouseDrag:
            {
                if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
                {
                    break;
                }
                if (GUIUtility.hotControl == base.shapeId && Event.current.button == 0)
                {
                    Event.current.Use();
                }
                return;
            }

            case EventType.MouseUp:
            {
                if (GUIUtility.hotControl != base.shapeId)
                {
                    return;
                }
                if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
                {
                    return;
                }
                if (Event.current.button == 0)
                {
                    Event.current.Use();

                    ResetVisuals();
                    if (onLastPoint)
                    {
                        GUIUtility.hotControl             = 0;
                        GUIUtility.keyboardControl        = 0;
                        EditorGUIUtility.editingTextField = false;

                        editMode = EditMode.CreateShape;
                        HotKeyReleased();
                    }
                }
                return;
            }
            }
            return;
        }
示例#27
0
 public void GenerateFromPolygon(Camera camera, CSGBrush brush, CSGPlane plane, Vector3 direction, Vector3[] meshVertices, int[] indices, uint[] smoothingGroups, bool drag, CSGOperationType forceDragSource, bool autoCommitExtrusion)
 {
     BuilderMode = ShapeMode.FreeDraw;
     freedrawGenerator.GenerateFromPolygon(camera, brush, plane, direction, meshVertices, indices, smoothingGroups, drag, forceDragSource, autoCommitExtrusion);
 }
示例#28
0
        protected override void HandleCreateShapeEvents(Rect sceneRect)
        {
            bool     pointOnEdge      = false;
            bool     havePlane        = false;
            bool     vertexOnGeometry = false;
            CSGBrush vertexOnBrush    = null;

            CSGPlane hoverBuildPlane = buildPlane;
            var      sceneView       = SceneView.currentDrawingSceneView; //(SceneView.currentDrawingSceneView != null) ? SceneView.currentDrawingSceneView : SceneView.lastActiveSceneView;
            var      camera          = sceneView.camera;

            if (camera != null &&
                camera.pixelRect.Contains(Event.current.mousePosition))
            {
                if (!hoverDefaultPlane.HasValue ||
                    settings.vertices.Length == 0)
                {
                    bool forceGrid = RealtimeCSG.CSGGrid.ForceGrid;
                    RealtimeCSG.CSGGrid.ForceGrid = false;
                    hoverDefaultPlane             = RealtimeCSG.CSGGrid.CurrentGridPlane;
                    RealtimeCSG.CSGGrid.ForceGrid = forceGrid;
                    firstSnappedEdges             = null;
                    firstSnappedBrush             = null;
                    firstSnappedPlanes            = null;
                    base.geometryModel            = null;
                }
                if (editMode == EditMode.CreatePlane)
                {
                    LegacyBrushIntersection intersection;
                    if (!IgnoreDepthForRayCasts(sceneView) && !havePlane &&
                        SceneQueryUtility.FindWorldIntersection(Event.current.mousePosition, out intersection))
                    {
                        worldPosition   = intersection.worldIntersection;
                        hoverBuildPlane = intersection.worldPlane;
                        vertexOnBrush   = intersection.brush;

                        vertexOnGeometry = true;
                    }
                    else
                    {
                        hoverBuildPlane = hoverDefaultPlane.Value;
                        vertexOnBrush   = null;

                        var mouseRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                        worldPosition    = hoverBuildPlane.RayIntersection(mouseRay);
                        vertexOnGeometry = false;
                    }
                    ResetVisuals();
                    if (snapFunction != null)
                    {
                        CSGBrush snappedOnBrush;
                        worldPosition = snapFunction(worldPosition, hoverBuildPlane, ref visualSnappedEdges, out snappedOnBrush, generatedBrushes, ignoreAllBrushes: true);
                        if (snappedOnBrush != null)
                        {
                            pointOnEdge = (visualSnappedEdges != null &&
                                           visualSnappedEdges.Count > 0);
                            vertexOnBrush    = snappedOnBrush;
                            vertexOnGeometry = true;
                        }
                    }

                    if (settings.vertices.Length == 1)
                    {
                        if (hoverBuildPlane.normal != MathConstants.zeroVector3)
                        {
                            editMode  = EditMode.CreateShape;
                            havePlane = true;
                        }
                    }
                }
                else
                {
                    var mouseRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                    if (settings.vertices.Length == 2)
                    {
                        var startPoint = settings.vertices[1];

                        var forward = camera.transform.forward;
                        if (Vector3.Dot(forward, gridBinormal) < Vector3.Dot(forward, gridTangent))
                        {
                            hoverBuildPlane = new CSGPlane(gridBinormal, startPoint);
                        }
                        else
                        {
                            hoverBuildPlane = new CSGPlane(gridTangent, startPoint);
                        }
                        worldPosition = hoverBuildPlane.RayIntersection(mouseRay);

                        // the third point is always straight up from the second point
                        //worldPosition = startPoint + (Vector3.Dot(worldPosition - startPoint, gridNormal) * gridNormal);

                        RealtimeCSG.CSGGrid.SetForcedGrid(hoverBuildPlane);
                        ResetVisuals();
                        if (raySnapFunction != null)
                        {
                            Ray      ray = new Ray(startPoint, gridNormal);
                            CSGBrush snappedOnBrush;
                            worldPosition = raySnapFunction(worldPosition, ray, ref visualSnappedEdges, out snappedOnBrush);
                            if (snappedOnBrush != null)
                            {
                                pointOnEdge = (visualSnappedEdges != null &&
                                               visualSnappedEdges.Count > 0);
                                vertexOnBrush = snappedOnBrush;
                            }
                        }

                        worldPosition = GeometryUtility.ProjectPointOnInfiniteLine(worldPosition, startPoint, gridNormal);
                    }
                    else
                    {
                        worldPosition = hoverBuildPlane.RayIntersection(mouseRay);

                        RealtimeCSG.CSGGrid.SetForcedGrid(hoverBuildPlane);
                        ResetVisuals();
                        if (snapFunction != null)
                        {
                            CSGBrush snappedOnBrush;
                            worldPosition = snapFunction(worldPosition, hoverBuildPlane, ref visualSnappedEdges, out snappedOnBrush, generatedBrushes, ignoreAllBrushes: true);
                            if (snappedOnBrush != null)
                            {
                                pointOnEdge = (visualSnappedEdges != null &&
                                               visualSnappedEdges.Count > 0);
                                vertexOnBrush = snappedOnBrush;
                            }
                        }
                    }
                }

                if (geometryModel == null && vertexOnBrush != null)
                {
                    if (vertexOnBrush.ChildData != null && vertexOnBrush.ChildData.Model)
                    {
                        geometryModel = vertexOnBrush.ChildData.Model;
                    }
                }

                if (worldPosition != prevWorldPosition)
                {
                    prevWorldPosition = worldPosition;
                    if (settings.vertices.Length > 0)
                    {
                        if ((settings.vertices[0] - worldPosition).sqrMagnitude > MathConstants.EqualityEpsilon)
                        {
                            UpdateSizes();
                            UpdateBaseShape(true);
                        }
                    }
                    if (Event.current.type != EventType.Repaint)
                    {
                        CSG_EditorGUIUtility.UpdateSceneViews();
                    }
                }

                visualSnappedGrid  = RealtimeCSG.CSGGrid.FindAllGridEdgesThatTouchPoint(worldPosition);
                visualSnappedBrush = vertexOnBrush;
            }
            RealtimeCSG.CSGGrid.SetForcedGrid(hoverBuildPlane);



            if (!SceneDragToolManager.IsDraggingObjectInScene &&
                Event.current.type == EventType.Repaint)
            {
                PaintSnapVisualisation();
                PaintShape(base.shapeId);
            }


            var type = Event.current.GetTypeForControl(base.shapeId);

            switch (type)
            {
            case EventType.Layout:
            {
                return;
            }

            case EventType.ValidateCommand:
            case EventType.KeyDown:
            {
                if (GUIUtility.hotControl == base.shapeId)
                {
                    if (Keys.PerformActionKey.IsKeyPressed() ||
                        Keys.DeleteSelectionKey.IsKeyPressed() ||
                        Keys.CancelActionKey.IsKeyPressed())
                    {
                        Event.current.Use();
                    }
                }
                return;
            }

            case EventType.KeyUp:
            {
                if (GUIUtility.hotControl == base.shapeId)
                {
                    if (Keys.CylinderBuilderMode.IsKeyPressed() ||
                        Keys.PerformActionKey.IsKeyPressed())
                    {
                        HotKeyReleased();
                        Event.current.Use();
                        return;
                    }
                    if (Keys.DeleteSelectionKey.IsKeyPressed() ||
                        Keys.CancelActionKey.IsKeyPressed())
                    {
                        Cancel();
                        Event.current.Use();
                        return;
                    }
                }
                return;
            }

            case EventType.MouseDown:
            {
                if (!sceneRect.Contains(Event.current.mousePosition))
                {
                    break;
                }
                if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
                {
                    return;
                }
                if ((GUIUtility.hotControl != 0 && GUIUtility.hotControl != shapeEditId && GUIUtility.hotControl != base.shapeId) ||
                    Event.current.button != 0)
                {
                    return;
                }

                Event.current.Use();
                if (settings.vertices.Length == 0)
                {
                    if ((GUIUtility.hotControl == 0 ||
                         GUIUtility.hotControl == base.shapeEditId) && base.shapeId != -1)
                    {
                        base.CalculateWorldSpaceTangents();
                        GUIUtility.hotControl             = base.shapeId;
                        GUIUtility.keyboardControl        = base.shapeId;
                        EditorGUIUtility.editingTextField = false;
                    }
                }

                if (GUIUtility.hotControl == base.shapeId &&
                    settings.vertices.Length < kMaxPoints)
                {
                    if (!float.IsNaN(worldPosition.x) && !float.IsInfinity(worldPosition.x) &&
                        !float.IsNaN(worldPosition.y) && !float.IsInfinity(worldPosition.y) &&
                        !float.IsNaN(worldPosition.z) && !float.IsInfinity(worldPosition.z))
                    {
                        if (settings.vertices.Length < 2 &&
                            hoverBuildPlane.normal.sqrMagnitude != 0)
                        {
                            buildPlane = hoverBuildPlane;
                        }
                        CalculateWorldSpaceTangents();

                        if (settings.vertices.Length == 0)
                        {
                            if (pointOnEdge)
                            {
                                firstSnappedEdges  = visualSnappedEdges.ToArray();
                                firstSnappedBrush  = visualSnappedBrush;
                                firstSnappedPlanes = null;
                            }
                            else
                            {
                                firstSnappedBrush  = null;
                                firstSnappedEdges  = null;
                                firstSnappedPlanes = null;
                            }
                            planeOnGeometry = vertexOnGeometry;
                        }
                        else
                        {
                            if (firstSnappedEdges != null)
                            {
                                if (firstSnappedPlanes == null)
                                {
                                    CreateSnappedPlanes();
                                }

                                bool outside = true;
                                for (int i = 0; i < firstSnappedPlanes.Length; i++)
                                {
                                    if (firstSnappedPlanes[i].Distance(worldPosition) <= MathConstants.DistanceEpsilon)
                                    {
                                        outside = false;
                                        break;
                                    }
                                }

                                planeOnGeometry = !outside;
                            }

                            if (vertexOnGeometry)
                            {
                                var plane    = hoverDefaultPlane.Value;
                                var distance = plane.Distance(worldPosition);
                                plane.d          += distance;
                                hoverDefaultPlane = plane;

                                for (int i = 0; i < settings.vertices.Length; i++)
                                {
                                    if (!settings.onGeometryVertices[i])
                                    {
                                        settings.SetPoint(i, GeometryUtility.ProjectPointOnPlane(plane, settings.vertices[i]));
                                        settings.onGeometryVertices[i] = true;
                                    }
                                }
                            }
                        }
                        ArrayUtility.Add(ref settings.onGeometryVertices, vertexOnGeometry);
                        settings.AddPoint(worldPosition);

                        UpdateSizes();
                        CSG_EditorGUIUtility.UpdateSceneViews();
                        if (settings.vertices.Length == kMaxPoints)
                        {
                            HotKeyReleased();
                        }
                    }
                }
                return;
            }

            case EventType.MouseDrag:
            {
                if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
                {
                    break;
                }
                if (GUIUtility.hotControl == base.shapeId && Event.current.button == 0)
                {
                    Event.current.Use();
                }
                return;
            }

            case EventType.MouseUp:
            {
                if (GUIUtility.hotControl != base.shapeId)
                {
                    return;
                }
                if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
                {
                    return;
                }
                if (Event.current.button == 0)
                {
                    Event.current.Use();

                    ResetVisuals();
                    if (settings.vertices.Length == kMaxPoints)
                    {
                        GUIUtility.hotControl             = 0;
                        GUIUtility.keyboardControl        = 0;
                        EditorGUIUtility.editingTextField = false;

                        editMode = EditMode.CreateShape;
                        HotKeyReleased();
                    }
                }
                return;
            }
            }
        }
        protected void HandleHeightHandles(SceneView sceneView, Rect sceneRect, bool showHeightValue)
        {
            var camera = sceneView.camera;

            for (int p = 0; p < extrusionPoints.Length; p++)
            {
                var type = Event.current.GetTypeForControl(extrusionPoints[p].ID);
                switch (type)
                {
                case EventType.Repaint:
                {
                    if (SceneDragToolManager.IsDraggingObjectInScene)
                    {
                        break;
                    }

                    bool isSelected = extrusionPoints[p].ID == GUIUtility.keyboardControl;
                    var  temp       = Handles.color;
                    var  origMatrix = Handles.matrix;

                    Handles.matrix = MathConstants.identityMatrix;
                    var rotation = camera.transform.rotation;


                    var state = SelectState.None;
                    if (isSelected)
                    {
                        state |= SelectState.Selected;
                        state |= SelectState.Hovering;
                    }
                    else
                    if (HandleUtility.nearestControl == extrusionPoints[p].ID)
                    {
                        state |= SelectState.Hovering;
                    }


                    if (polygons != null && outlineVertices.Length >= 3)
                    {
                        var wireframeColor    = ColorSettings.WireframeOutline;
                        var topWireframeColor = ColorSettings.WireframeOutline;

                        if (!shapeIsValid)
                        {
                            wireframeColor = Color.red;
                        }

                        var surfaceColor = ColorSettings.ShapeDrawingFill;
                        if (GUIUtility.hotControl == extrusionPoints[p].ID)
                        {
                            topWireframeColor = ColorSettings.BoundsEdgeHover;
                            surfaceColor      = ColorSettings.PolygonInnerStateColor[(int)(SelectState.Selected | SelectState.Hovering)];
                            surfaceColor.a   *= 0.5f;
                        }
                        else
                        if (GUIUtility.hotControl == 0 && HandleUtility.nearestControl == extrusionPoints[p].ID)
                        {
                            topWireframeColor = ColorSettings.BoundsEdgeHover;
                            surfaceColor      = ColorSettings.PolygonInnerStateColor[(int)(SelectState.Selected)];
                            surfaceColor.a   *= 0.5f;
                        }


                        var poly2dToWorldMatrix = Matrix4x4.TRS(extrusionPoints[p].Position, Quaternion.FromToRotation(MathConstants.upVector3, buildPlane.normal), MathConstants.oneVector3);
                        for (int i = 0; i < polygons.Length; i++)
                        {
                            PaintUtility.DrawPolygon(poly2dToWorldMatrix, polygons[i].Vertices, surfaceColor);
                        }

                        poly2dToWorldMatrix = Matrix4x4.TRS(extrusionPoints[p].Position, Quaternion.identity, MathConstants.oneVector3);
                        for (int i = 1; i < outlineVertices.Length; i++)
                        {
                            PaintUtility.DrawLine(poly2dToWorldMatrix, outlineVertices[i - 1], outlineVertices[i], GUIConstants.oldLineScale, topWireframeColor);
                            PaintUtility.DrawDottedLine(poly2dToWorldMatrix, outlineVertices[i - 1], outlineVertices[i], topWireframeColor, 4.0f);
                        }
                        PaintUtility.DrawLine(poly2dToWorldMatrix, outlineVertices[outlineVertices.Length - 1], outlineVertices[0], GUIConstants.oldLineScale, topWireframeColor);
                        PaintUtility.DrawDottedLine(poly2dToWorldMatrix, outlineVertices[outlineVertices.Length - 1], outlineVertices[0], topWireframeColor, 4.0f);

                        if (p > 0)
                        {
                            var prevOffset = extrusionPoints[p - 1].Position;
                            var prevPoly2dToWorldMatrix = Matrix4x4.TRS(prevOffset, Quaternion.identity, MathConstants.oneVector3);
                            for (int i = 0; i < outlineVertices.Length; i++)
                            {
                                var from = prevPoly2dToWorldMatrix.MultiplyPoint(outlineVertices[i]);
                                var to   = poly2dToWorldMatrix.MultiplyPoint(outlineVertices[i]);
                                PaintUtility.DrawLine(from, to, GUIConstants.oldLineScale, wireframeColor);
                                PaintUtility.DrawDottedLine(from, to, wireframeColor, 4.0f);
                            }
                        }
                    }

                    var color = ColorSettings.PolygonInnerStateColor[(int)state];
                    if (!shapeIsValid)
                    {
                        color = Color.red;
                    }

                    var handleSize       = CSG_HandleUtility.GetHandleSize(extrusionPoints[p].Position);
                    var scaledHandleSize = handleSize * GUIConstants.handleScale;
                    if (p > 0)
                    {
                        PaintUtility.DrawDottedLine(extrusionPoints[p - 1].Position, extrusionPoints[p].Position, color, 4.0f);
                    }

                    Handles.color = color;
                    PaintUtility.SquareDotCap(extrusionPoints[p].ID, extrusionPoints[p].Position, rotation, scaledHandleSize);

                    var direction = haveForcedDirection ? forcedDirection : buildPlane.normal;

                    var distance = new CSGPlane(direction, extrusionPoints[p].Position).Distance(extrusionPoints[1 - p].Position);
                    if (distance <= MathConstants.DistanceEpsilon)
                    {
                        PaintUtility.DrawArrowCap(extrusionPoints[p].Position, direction, HandleUtility.GetHandleSize(extrusionPoints[p].Position));
                    }
                    if (distance > -MathConstants.DistanceEpsilon)
                    {
                        PaintUtility.DrawArrowCap(extrusionPoints[p].Position, -direction, HandleUtility.GetHandleSize(extrusionPoints[p].Position));
                    }

                    Handles.matrix = origMatrix;
                    Handles.color  = temp;

                    if (p > 0 && showHeightValue)
                    {
                        var length = GetSegmentLength(extrusionPoints[p].Position, extrusionPoints[p - 1].Position, direction);
                        PaintHeightMessage(camera, extrusionPoints[p - 1].Position, extrusionPoints[p].Position, gridTangent, length);
                    }
                    break;
                }

                case EventType.Layout:
                {
                    if ((Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan))
                    {
                        break;
                    }

                    var poly2dToWorldMatrix = Matrix4x4.TRS(extrusionPoints[p].Position, Quaternion.FromToRotation(MathConstants.upVector3, buildPlane.normal), MathConstants.oneVector3);
                    var forceOverHandle     = IsMouseOverShapePolygons(poly2dToWorldMatrix);
                    HandleUtility.AddControl(extrusionPoints[p].ID, forceOverHandle ? 3.0f : float.PositiveInfinity);

                    var origMatrix = Handles.matrix;
                    Handles.matrix = MathConstants.identityMatrix;
                    float handleSize       = CSG_HandleUtility.GetHandleSize(extrusionPoints[p].Position);
                    float scaledHandleSize = handleSize * GUIConstants.handleScale * handle_extension;
                    float distanceToCircle = HandleUtility.DistanceToCircle(extrusionPoints[p].Position, scaledHandleSize);

                    HandleUtility.AddControl(extrusionPoints[p].ID, distanceToCircle);

                    var direction = haveForcedDirection ? forcedDirection : buildPlane.normal;

                    var distance = new CSGPlane(direction, extrusionPoints[p].Position).Distance(extrusionPoints[1 - p].Position);
                    if (distance <= MathConstants.DistanceEpsilon)
                    {
                        PaintUtility.AddArrowCapControl(extrusionPoints[p].ID, extrusionPoints[p].Position, direction, HandleUtility.GetHandleSize(extrusionPoints[p].Position));
                    }
                    if (distance > -MathConstants.DistanceEpsilon)
                    {
                        PaintUtility.AddArrowCapControl(extrusionPoints[p].ID, extrusionPoints[p].Position, -direction, HandleUtility.GetHandleSize(extrusionPoints[p].Position));
                    }

                    if (generatedGameObjects != null && generatedGameObjects.Length > 0)
                    {
                        for (int g = generatedGameObjects.Length - 1; g >= 0; g--)
                        {
                            if (generatedGameObjects[g])
                            {
                                continue;
                            }
                            ArrayUtility.RemoveAt(ref generatedGameObjects, g);
                        }

                        if (generatedGameObjects == null || generatedGameObjects.Length == 0)
                        {
                            Cancel();
                        }
                    }

                    Handles.matrix = origMatrix;
                    break;
                }

                case EventType.MouseDown:
                {
                    if (!sceneRect.Contains(Event.current.mousePosition))
                    {
                        break;
                    }
                    if ((Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan) ||
                        Event.current.modifiers != EventModifiers.None)
                    {
                        break;
                    }
                    if (GUIUtility.hotControl == 0 &&
                        HandleUtility.nearestControl == extrusionPoints[p].ID && Event.current.button == 0)
                    {
                        if (editMode != EditMode.ExtrudeShape &&
                            !StartExtrudeMode(camera))
                        {
                            Cancel();
                        }
                        else
                        {
                            UpdateBaseShape(registerUndo: false);
                            dragPositionStart = extrusionPoints[p].Position;
                            GrabHeightHandle(sceneView, p);
                            BeginExtrusion();
                            Event.current.Use();
                        }
                    }
                    break;
                }

                case EventType.MouseDrag:
                case EventType.MouseMove:
                {
                    if (Tools.viewTool != ViewTool.None && Tools.viewTool != ViewTool.Pan)
                    {
                        break;
                    }
                    if (GUIUtility.hotControl == extrusionPoints[p].ID)                            // && Event.current.button == 0)
                    {
                        Undo.RecordObject(this, "Extrude shape");
                        heightPosition += Event.current.delta;
                        Vector3 worldPosition = GetHeightHandlePosition(sceneView, extrusionPoints[p].Position) - heightHandleOffset;
                        if (float.IsInfinity(worldPosition.x) || float.IsNaN(worldPosition.x) ||
                            float.IsInfinity(worldPosition.y) || float.IsNaN(worldPosition.y) ||
                            float.IsInfinity(worldPosition.z) || float.IsNaN(worldPosition.z))
                        {
                            worldPosition = extrusionPoints[p].Position;
                        }

                        ResetVisuals();
                        if (raySnapFunction != null)
                        {
                            CSGBrush snappedOnBrush = null;
                            worldPosition      = raySnapFunction(camera, worldPosition, new Ray(brushPosition, movePolygonDirection), ref visualSnappedEdges, out snappedOnBrush);
                            visualSnappedBrush = snappedOnBrush;
                        }

                        visualSnappedGrid = RealtimeCSG.CSGGrid.FindAllGridEdgesThatTouchPoint(camera, worldPosition);

                        extrusionPoints[p].Position = GeometryUtility.ProjectPointOnInfiniteLine(worldPosition, brushPosition, movePolygonDirection);

                        if (p == 0)
                        {
                            MoveShape(extrusionPoints[0].Position - dragPositionStart);
                            UpdateBaseShape();
                        }

                        UpdateBrushPosition();
                        UpdateExtrudedShape();

                        GUI.changed = true;
                        Event.current.Use();
                        break;
                    }
                    break;
                }

                case EventType.MouseUp:
                {
                    forceDragHandle = false;
                    //forceDragSource = null;
                    if (GUIUtility.hotControl == extrusionPoints[p].ID &&
                        Event.current.button == 0 &&
                        (Tools.viewTool == ViewTool.None || Tools.viewTool == ViewTool.Pan))
                    {
                        EndExtrusion();
                        if (firstClick)
                        {
                            firstClick = false;
                            break;
                        }

                        GUIUtility.hotControl             = 0;
                        GUIUtility.keyboardControl        = 0;
                        EditorGUIUtility.editingTextField = false;
                        Event.current.Use();

                        ResetVisuals();
                        CleanupGrid();

                        if (!HaveExtrusion)
                        {
                            RevertToEditVertices();
                        }

                        if (commitExtrusionAfterRelease)
                        {
                            var prevGeneratedBrushes = generatedBrushes;
                            Commit(camera);
                            // did we switch to edit mode?
                            if (EditModeManager.EditMode == ToolEditMode.Edit &&
                                prevGeneratedBrushes != null)
                            {
                                EditModeManager.UpdateTool();
                                EditModeManager.UpdateSelection(true);
                                var tool = EditModeManager.ActiveTool as EditModeMeshEdit;
                                if (tool)
                                {
                                    var brush        = prevGeneratedBrushes[0];
                                    var polygonCount = brush.ControlMesh.Polygons.Length;
                                    tool.SelectPolygon(brush, polygonCount - 2);                                             // select front most polygon
                                }
                            }
                        }
                        break;
                    }
                    break;
                }
                }
            }

            var shapeType = Event.current.GetTypeForControl(shapeId);

            HandleKeyboard(shapeType);
        }
        protected bool UpdateExtrudedShape(bool registerUndo = true)
        {
            if (polygons == null || polygons.Length == 0)
            {
                return(false);
            }

            bool failures          = false;
            bool modifiedHierarchy = false;

            if (HaveExtrusion)
            {
                UpdateBrushOperation();

                if (generatedGameObjects != null && generatedGameObjects.Length > 0)
                {
                    for (int i = generatedGameObjects.Length - 1; i >= 0; i--)
                    {
                        if (generatedGameObjects[i])
                        {
                            continue;
                        }
                        ArrayUtility.RemoveAt(ref generatedGameObjects, i);
                    }
                }
                if (generatedGameObjects == null || generatedGameObjects.Length == 0)
                {
                    Cancel();
                    return(false);
                }

                if (generatedGameObjects != null && generatedGameObjects.Length > 0)
                {
                    if (registerUndo)
                    {
                        Undo.RecordObjects(generatedGameObjects, "Extruded shape");
                    }

                    int brushIndex = 0;
                    for (int slice = 0; slice < extrusionPoints.Length - 1; slice++)
                    {
                        for (int p = 0; p < polygons.Length; p++)
                        {
                            var brush = generatedBrushes[brushIndex]; brushIndex++;

                            if (!brush || !brush.gameObject)
                            {
                                continue;
                            }

                            var direction = haveForcedDirection ? forcedDirection : buildPlane.normal;
                            var distance  = new CSGPlane(direction, extrusionPoints[slice].Position).Distance(extrusionPoints[slice + 1].Position);
                            if (float.IsInfinity(distance) || float.IsNaN(distance))
                            {
                                distance = 1.0f;
                            }

                            var poly2dToWorldMatrix = brush.transform.worldToLocalMatrix *
                                                      Matrix4x4.TRS(extrusionPoints[slice].Position, Quaternion.FromToRotation(MathConstants.upVector3, buildPlane.normal),
                                                                    Vector3.one);                                                                             // * parentModel.transform.localToWorldMatrix;


                            ControlMesh newControlMesh;
                            Shape       newShape;
                            if (!CreateControlMeshForBrushIndex(parentModel, brush, polygons[p], poly2dToWorldMatrix, distance, out newControlMesh, out newShape))
                            {
                                failures = true;
                                if (brush.gameObject.activeSelf)
                                {
                                    modifiedHierarchy = true;
                                    brush.gameObject.SetActive(false);
                                }
                                continue;
                            }

                            if (!brush.gameObject.activeSelf)
                            {
                                modifiedHierarchy = true;
                                brush.gameObject.SetActive(true);
                            }

                            brush.ControlMesh.SetDirty();
                            if (registerUndo)
                            {
                                EditorUtility.SetDirty(brush);
                            }
                        }
                    }
                }
            }
            else
            {
                if (generatedGameObjects != null)
                {
                    if (registerUndo)
                    {
                        Undo.RecordObjects(generatedGameObjects, "Extruded brush");
                    }
                    InternalCSGModelManager.skipCheckForChanges = false;
                    int brushIndex = 0;
                    for (int slice = 0; slice < extrusionPoints.Length - 1; slice++)
                    {
                        for (int p = 0; p < polygons.Length; p++)
                        {
                            if (p >= generatedBrushes.Length)
                            {
                                continue;
                            }
                            var brush = generatedBrushes[brushIndex];
                            brushIndex++;
                            brush.ControlMesh.SetDirty();
                            if (registerUndo)
                            {
                                EditorUtility.SetDirty(brush);
                            }
                        }
                    }
                    HideGenerateBrushes();
                }
            }

            try
            {
                InternalCSGModelManager.skipCheckForChanges = true;
                if (registerUndo)
                {
                    EditorUtility.SetDirty(this);
                }
                //CSGModelManager.External.SetDirty(parentModel.modelNodeID);
                InternalCSGModelManager.CheckForChanges(forceHierarchyUpdate: modifiedHierarchy);
            }
            finally
            {
                InternalCSGModelManager.skipCheckForChanges = false;
            }

            if (shapeEdges != null && smearTextures)
            {
                CSGBrush lastBrush        = null;
                int      lastSurfaceIndex = -1;
                for (int slice = 0; slice < extrusionPoints.Length - 1; slice++)
                {
                    for (int se = 0; se < shapeEdges.Length; se++)
                    {
                        var brushIndex   = shapeEdges[se].PolygonIndex + (slice * shapeEdges.Length);
                        var surfaceIndex = shapeEdges[se].EdgeIndex;

                        if (brushIndex < 0 ||
                            brushIndex >= generatedBrushes.Length ||
                            surfaceIndex == -1)
                        {
                            continue;
                        }

                        var brush = generatedBrushes[brushIndex];
                        if (brush && brush.brushNodeID != CSGNode.InvalidNodeID)
                        {
                            if (lastBrush && lastBrush.brushNodeID != CSGNode.InvalidNodeID)
                            {
                                SurfaceUtility.CopyLastMaterial(brush, surfaceIndex, false,
                                                                lastBrush, lastSurfaceIndex, false,
                                                                registerUndo = false);
                            }
                            else
                            {
                                brush.Shape.TexGens[surfaceIndex].Translation   = Vector3.zero;
                                brush.Shape.TexGens[surfaceIndex].Scale         = Vector2.one;
                                brush.Shape.TexGens[surfaceIndex].RotationAngle = 0;
                            }
                            lastBrush        = brush;
                            lastSurfaceIndex = surfaceIndex;
                        }
                    }
                }
            }
            InternalCSGModelManager.RefreshMeshes();

            return(!failures);
        }