static void CSG4Split() { string layoutsPath = Path.Combine(InternalEditorUtility.unityPreferencesFolder, "Layouts"); string filePath = Path.Combine(layoutsPath, "4 Split.wlt"); EditorUtility.LoadWindowLayout(filePath); for (int i = 0; i < 4; i++) { SceneView sceneView = ((SceneView)SceneView.sceneViews[i]); if (EditorHelper.GetSceneViewCamera(sceneView) == EditorHelper.SceneViewCamera.Other) { sceneView.orthographic = false; sceneView.m_SceneLighting = true; } else { sceneView.orthographic = true; sceneView.m_SceneLighting = false; SceneView.SceneViewState state = GetSceneViewState(sceneView); state.Toggle(false); } } SceneView.RepaintAll(); }
private Plane GetActivePlane() { if (Camera.current.orthographic && EditorHelper.GetSceneViewCamera(Camera.current) != EditorHelper.SceneViewCamera.Other) { // Axis aligned iso view return(new Plane() { normal = -Camera.current.transform.forward, distance = 0 }); } else { if (activePolygon != null) { // A polygon plane is overriding the grid plane, so return that return(activePolygon.Plane); } else { // No plane override, so use ground plane return(new Plane() { normal = Vector3.up, distance = 0 }); } } }
private Polygon GetActivePolygon() { if (Camera.current.orthographic && EditorHelper.GetSceneViewCamera(Camera.current) != EditorHelper.SceneViewCamera.Other) { // Axis aligned iso view return(null); } else { return(activePolygon); } }
private PolygonRaycastHit?CalculateHitPolygon(Vector2 currentPosition) { if (EditorHelper.GetSceneViewCamera(SceneView.lastActiveSceneView) == EditorHelper.SceneViewCamera.Other) { // Convert the mouse position into a ray to intersect with a plane in the world Ray currentRay = Camera.current.ScreenPointToRay(EditorHelper.ConvertMousePointPosition(currentPosition)); List <PolygonRaycastHit> hits = csgModel.RaycastBrushesAll(currentRay, false); if (hits.Count > 0) { return(hits[0]); } else { return(null); } } else { // If the scene view is axis-aligned iso then we don't raycast polygons return(null); } }
static Plane GetActivePlane() { SceneView activeSceneView = SceneView.lastActiveSceneView; if (activeSceneView != null && activeSceneView.camera != null && activeSceneView.camera.orthographic && EditorHelper.GetSceneViewCamera(activeSceneView.camera) != EditorHelper.SceneViewCamera.Other) { // Axis aligned iso view return(new Plane() { normal = -SceneView.lastActiveSceneView.camera.transform.forward, distance = 0 }); } else { // No plane override, so use ground plane return(new Plane() { normal = Vector3.up, distance = 0 }); } }
static float CalculateWorldUnitScreenSize(Camera camera, float worldUnits) { EditorHelper.SceneViewCamera cameraOrientation = EditorHelper.GetSceneViewCamera(camera); bool orthographicAxisAligned = camera.orthographic && cameraOrientation != EditorHelper.SceneViewCamera.Other; Transform transform = camera.transform; if (orthographicAxisAligned) { float cameraHeight = camera.orthographicSize * 2; float cameraWidth = camera.aspect * cameraHeight; return(worldUnits * (float)Screen.width / cameraWidth); } else { float distanceFromGrid = Mathf.Abs(transform.position.y); if (distanceFromGrid < 1) { distanceFromGrid = 1; } Vector3 worldCenter = transform.position + transform.forward * distanceFromGrid; Vector3 rightVector = transform.right; Vector3 worldPoint1 = worldCenter - rightVector * worldUnits * 0.5f; Vector3 worldPoint2 = worldCenter + rightVector * worldUnits * 0.5f; Vector3 screenPoint1 = camera.WorldToScreenPoint(worldPoint1); Vector3 screenPoint2 = camera.WorldToScreenPoint(worldPoint2); return(screenPoint2.x - screenPoint1.x); } }
private static void Draw() { SceneView sceneView = SceneView.currentDrawingSceneView; // If the user has turned on hiding of perspectve grid then hide it if perspective if (!sceneView.orthographic && CurrentSettings.HideGridInPerspective) { return; } // Cache additional references Camera camera = sceneView.camera; Transform transform = camera.transform; float fullSnapDistance = CurrentSettings.PositionSnapDistance; float snapDistance = fullSnapDistance; // Calculate various camera positions and its orientation EditorHelper.SceneViewCamera cameraOrientation = EditorHelper.GetSceneViewCamera(sceneView); // True if the camera is both orthographic (iso) and axis-aligned bool orthographicAxisAligned = sceneView.orthographic && cameraOrientation != EditorHelper.SceneViewCamera.Other; Vector3 cameraPosition = transform.position; Vector3 roundedCameraPosition = MathHelper.RoundVector3(cameraPosition, snapDistance); // Calculate the world vectors to use for the X and Y grid axes Vector3 xDirection = orthographicAxisAligned ? transform.right : Vector3.right; Vector3 yDirection = orthographicAxisAligned ? transform.up : Vector3.forward; // Now calculate a depth offset to help with dealing with objects far from the origin Vector3 depthOffset = Vector3.zero; if (orthographicAxisAligned) { float depthFudge = 1; depthOffset = transform.forward * (camera.nearClipPlane + depthFudge + Vector3.Dot(cameraPosition, transform.forward)); // Debug.Log(camera.nearClipPlane + " to " + camera.farClipPlane); // Debug.Log(depthOffset); } else { depthOffset = Vector3.zero; } // Line colors Color normalLine = new Color32(200, 200, 200, 128); Color smallestLine = new Color32(50, 50, 50, 128); Color xAxisColor = ColorForVector(xDirection); Color yAxisColor = ColorForVector(yDirection); // How many lines to draw in each axis int xCount; int yCount; // Center point of the grid in each axis int xMid; int yMid; bool scaledUp = false; // Width of one world unit in screen pixels float gridWidthPixels = CalculateWorldUnitScreenSize(camera, 1); if (snapDistance >= 8) { gridWidthPixels = CalculateWorldUnitScreenSize(camera, snapDistance); } if (gridWidthPixels < MIN_VISIBLE) { if (snapDistance > 8) { snapDistance = Mathf.Pow(Mathf.Floor(Mathf.Log(snapDistance, 8)), 8); gridWidthPixels = CalculateWorldUnitScreenSize(camera, snapDistance); } while (gridWidthPixels < MIN_VISIBLE) { if (snapDistance < 8) { snapDistance = 8; } else { snapDistance *= 8; } scaledUp = true; gridWidthPixels = CalculateWorldUnitScreenSize(camera, snapDistance); } } // Alpha of the granular lines, generally based on distance float minorLineAlphaMultiplier = Mathf.InverseLerp(MIN_VISIBLE, MAX_VISIBLE, gridWidthPixels); float sanityScalar = Mathf.Max(1, snapDistance) * Mathf.Lerp(2, 1, minorLineAlphaMultiplier); if (orthographicAxisAligned) { float cameraHeight = camera.orthographicSize * 2; float cameraWidth = camera.aspect * cameraHeight; xCount = Mathf.CeilToInt(cameraWidth / snapDistance); yCount = Mathf.CeilToInt(cameraHeight / snapDistance); xMid = (int)(Vector3.Dot(roundedCameraPosition, xDirection) / snapDistance); yMid = (int)(Vector3.Dot(roundedCameraPosition, yDirection) / snapDistance); } else { List <Vector3> pointsInGrid = GetGridMinMax(camera); Vector3 pivotPointOnGrid = sceneView.pivot; pivotPointOnGrid.y = 0; pointsInGrid.Add(pivotPointOnGrid); Vector3 min = pointsInGrid[0]; Vector3 max = pointsInGrid[0]; // Calculate min,max for (int i = 1; i < pointsInGrid.Count; i++) { min.x = Mathf.Min(pointsInGrid[i].x, min.x); min.z = Mathf.Min(pointsInGrid[i].z, min.z); max.x = Mathf.Max(pointsInGrid[i].x, max.x); max.z = Mathf.Max(pointsInGrid[i].z, max.z); } // Ensure the grid isn't crazily big min.x = Mathf.Max(min.x, pivotPointOnGrid.x - MAJOR_LINE_DISTANCE * sanityScalar); min.z = Mathf.Max(min.z, pivotPointOnGrid.z - MAJOR_LINE_DISTANCE * sanityScalar); max.x = Mathf.Min(max.x, pivotPointOnGrid.x + MAJOR_LINE_DISTANCE * sanityScalar); max.z = Mathf.Min(max.z, pivotPointOnGrid.z + MAJOR_LINE_DISTANCE * sanityScalar); // Now calculate grid line count xCount = Mathf.CeilToInt((max.x - min.x) / snapDistance); yCount = Mathf.CeilToInt((max.z - min.z) / snapDistance); xMid = Mathf.RoundToInt((min.x + max.x) / 2f / snapDistance); yMid = Mathf.RoundToInt((min.z + max.z) / 2f / snapDistance); } // Pad out the edge case xCount += 2; yCount += 2; int xStart = xMid - xCount / 2; int yStart = yMid - yCount / 2; int xEnd = xMid + xCount / 2; int yEnd = yMid + yCount / 2; Vector3 cameraPositionOnPlane = new Vector3(transform.position.x, 0, transform.position.z); // Start rendering SabreGraphics.GetSelectedBrushMaterial().SetPass(0); GL.Begin(GL.LINES); int lineDistributonWorld = 8; while (lineDistributonWorld <= snapDistance) { lineDistributonWorld *= 8; } // Calculate repetition count of the distribution lines int lineDistributionCount; if (snapDistance < lineDistributonWorld) { lineDistributionCount = (int)(lineDistributonWorld / snapDistance); } else { lineDistributionCount = 1; } int gridJump = 8; // Ensure we don't split grid lines at too high a density when drawing as that would kill performance if (snapDistance < 1) { gridJump = Mathf.RoundToInt(gridJump / snapDistance); } for (int y = yStart; y <= yEnd; y++) { Color sourceColor = normalLine; bool majorLine = true; if (y == 0) { sourceColor = xAxisColor; } else if (y % lineDistributionCount != 0) { majorLine = false; if (!scaledUp) { sourceColor = smallestLine; } sourceColor.a *= minorLineAlphaMultiplier * 0.6f; } float activeDistance = sanityScalar * (majorLine ? MAJOR_LINE_DISTANCE : MINOR_LINE_DISTANCE); for (int x = xStart; x < xEnd; x += gridJump) { Color color = sourceColor; Vector3 yOffset = y * yDirection * snapDistance; Vector3 center = depthOffset + yOffset; Vector3 testPoint = center + xDirection * (x + gridJump / 2f) * snapDistance; testPoint.y = 0; float squareDistance = (testPoint - cameraPositionOnPlane).sqrMagnitude; if (squareDistance > (activeDistance * activeDistance)) { continue; } float distance = Mathf.Sqrt(squareDistance); color.a *= Mathf.InverseLerp(activeDistance, activeDistance / 2f, distance); GL.Color(color); GL.Vertex(center + xDirection * (x + 0) * snapDistance); GL.Vertex(center + xDirection * (x + gridJump) * snapDistance); } } for (int x = xStart; x <= xEnd; x++) { Color sourceColor = normalLine; bool majorLine = true; if (x == 0) { sourceColor = yAxisColor; } else if (x % lineDistributionCount != 0) { majorLine = false; if (!scaledUp) { sourceColor = smallestLine; } sourceColor.a *= minorLineAlphaMultiplier * 0.6f; } float activeDistance = sanityScalar * (majorLine ? MAJOR_LINE_DISTANCE : MINOR_LINE_DISTANCE); for (int y = yStart; y < yEnd; y += gridJump) { Color color = sourceColor; Vector3 xOffset = x * xDirection * snapDistance; Vector3 center = depthOffset + xOffset; Vector3 testPoint = center + yDirection * (y + gridJump / 2f) * snapDistance; testPoint.y = 0; float squareDistance = (testPoint - cameraPositionOnPlane).sqrMagnitude; if (squareDistance > (activeDistance * activeDistance)) { continue; } float distance = Mathf.Sqrt(squareDistance); color.a *= Mathf.InverseLerp(activeDistance, activeDistance * 0.5f, distance); GL.Color(color); GL.Vertex(center + yDirection * (y + 0) * snapDistance); GL.Vertex(center + yDirection * (y + gridJump) * snapDistance); } } GL.End(); }
public override void OnSceneGUI(SceneView sceneView, Event e) { base.OnSceneGUI(sceneView, e); // Allow the base logic to calculate first // If any points are selected let the handles move them if (pointSelected > -1) { EditorGUI.BeginChangeCheck(); // Display a handle and allow the user to determine a new position in world space Vector3 newWorldPosition = Handles.PositionHandle(points[pointSelected], Quaternion.identity); if (EditorGUI.EndChangeCheck()) { Vector3 newPosition = newWorldPosition; Vector3 accumulatedDelta = newPosition - startPosition; if (CurrentSettings.PositionSnappingEnabled) { float snapDistance = CurrentSettings.PositionSnapDistance; accumulatedDelta = MathHelper.RoundVector3(accumulatedDelta, snapDistance); } newPosition = startPosition + accumulatedDelta; points[pointSelected] = newPosition; e.Use(); } } // First let's see if we can select any existing points if (e.type == EventType.MouseDown || e.type == EventType.MouseUp) { if (!EditorHelper.IsMousePositionNearSceneGizmo(e.mousePosition)) { OnMouseSelection(sceneView, e); } } if (e.button == 0 && e.type == EventType.MouseDrag && !CameraPanInProgress) { planeEstablished = false; } // Forward specific events on to handlers if (e.type == EventType.MouseDown || e.type == EventType.MouseUp || e.type == EventType.MouseDrag || e.type == EventType.MouseMove) { if (sceneView.camera.orthographic && EditorHelper.GetSceneViewCamera(sceneView) != EditorHelper.SceneViewCamera.Other) { OnMouseActionOrthographic(sceneView, e); } else { OnMouseAction3D(sceneView, e); } } else if (e.type == EventType.Repaint || e.type == EventType.Layout) { OnRepaint(sceneView, e); } else if (e.type == EventType.KeyDown || e.type == EventType.KeyUp) { OnKeyAction(sceneView, e); } }
void OnRepaint(SceneView sceneView, Event e) { if (primaryTargetBrush != null) { // Use a helper method to draw a visualisation of the clipping plane float largestExtent = GetBounds().GetLargestExtent(); float planeSize = largestExtent * 4f; // clipPlane. SabreGraphics.DrawPlane(displayPlane, planePosition, new Color(0f, 1f, 0f, .3f), new Color(1f, 0f, 0f, .3f), planeSize); // Selected brush green outline SabreGraphics.GetSelectedBrushMaterial().SetPass(0); // Draw black lines where the clip plane intersects the brushes if (!sceneView.camera.orthographic || EditorHelper.GetSceneViewCamera(sceneView) == EditorHelper.SceneViewCamera.Other) { GL.Begin(GL.LINES); GL.Color(Color.black); foreach (PrimitiveBrush brush in targetBrushes) { Polygon[] polygons = brush.GenerateTransformedPolygons(); foreach (Polygon polygon in polygons) { Vector3 position1; Vector3 position2; if (Polygon.PlanePolygonIntersection(polygon, out position1, out position2, displayPlane)) { GL.Vertex(position1); GL.Vertex(position2); } } } GL.End(); } if (displayPoint) { Camera sceneViewCamera = sceneView.camera; SabreGraphics.GetVertexMaterial().SetPass(0); GL.PushMatrix(); GL.LoadPixelMatrix(); GL.Begin(GL.QUADS); // Draw points in reverse order because we want the precedence to be Red, Green, Blue GL.Color(Color.blue); Vector3 target = sceneViewCamera.WorldToScreenPoint(points[2]); if (target.z > 0) { // Make it pixel perfect target = MathHelper.RoundVector3(target); SabreGraphics.DrawBillboardQuad(target, 8, 8); } GL.Color(Color.green); target = sceneViewCamera.WorldToScreenPoint(points[1]); if (target.z > 0) { // Make it pixel perfect target = MathHelper.RoundVector3(target); SabreGraphics.DrawBillboardQuad(target, 8, 8); } GL.Color(Color.red); target = sceneViewCamera.WorldToScreenPoint(points[0]); if (target.z > 0) { // Make it pixel perfect target = MathHelper.RoundVector3(target); SabreGraphics.DrawBillboardQuad(target, 8, 8); } GL.End(); GL.PopMatrix(); } } // Draw UI specific to this editor // GUI.backgroundColor = Color.red; Rect rectangle = new Rect(0, 50, 210, 130); GUIStyle toolbar = new GUIStyle(EditorStyles.toolbar); toolbar.normal.background = SabreGraphics.ClearTexture; toolbar.fixedHeight = rectangle.height; GUILayout.Window(140006, rectangle, OnToolbarGUI, "", toolbar); }