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); }
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); }
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; }
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(); }
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);*/ }
public static void SetPivotToLocalCenter(CSGBrush brush) { if (!brush) { return; } var localCenter = BoundsUtilities.GetLocalCenter(brush); var worldCenter = brush.transform.localToWorldMatrix.MultiplyPoint(localCenter); SetPivot(brush, worldCenter); }
public SelectedBrushSurface[] HoverOnBrush(CSGBrush hoverBrush, int surfaceIndex) { if (!hoverBrush) { return(null); } return(new SelectedBrushSurface[] { new SelectedBrushSurface(hoverBrush, surfaceIndex) }); }
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); }
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); }
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); }
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); } }
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; } }
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); }
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);
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; }
protected void ResetVisuals() { visualSnappedEdges = null; visualSnappedGrid = null; visualSnappedBrush = null; }
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; } } }
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); }
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); }
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; }
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); }
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); }