static void DrawOutline(CSGSphereDefinition definition, Vector3[] vertices, LineMode lineMode) { //var baseColor = UnityEditor.Handles.yAxisColor; //var isDisabled = UnitySceneExtensions.Handles.disabled; //var normal = Vector3.up; var sides = definition.horizontalSegments; var extraVertices = 2; var bottomVertex = 1; var topVertex = 0; var rings = (vertices.Length - extraVertices) / sides; var prevColor = UnityEditor.Handles.color; var color = prevColor; color.a *= 0.6f; UnityEditor.Handles.color = color; for (int i = 0, j = extraVertices; i < rings; i++, j += sides) { CSGOutlineRenderer.DrawLineLoop(vertices, j, sides, lineMode: lineMode, thickness: kHorzLineThickness, dashSize: kLineDash); } for (int k = 0; k < sides; k++) { CSGOutlineRenderer.DrawLine(vertices[topVertex], vertices[extraVertices + k], lineMode: lineMode, thickness: kVertLineThickness); for (int i = 0, j = extraVertices; i < rings - 1; i++, j += sides) { CSGOutlineRenderer.DrawLine(vertices[j + k], vertices[j + k + sides], lineMode: lineMode, thickness: kVertLineThickness); } CSGOutlineRenderer.DrawLine(vertices[bottomVertex], vertices[extraVertices + k + ((rings - 1) * sides)], lineMode: lineMode, thickness: kVertLineThickness); } UnityEditor.Handles.color = prevColor; }
static void DrawOutline(CSGCapsuleDefinition definition, Vector3[] vertices, LineMode lineMode) { //var baseColor = UnityEditor.Handles.yAxisColor; //var isDisabled = UnitySceneExtensions.Handles.disabled; //var normal = Vector3.up; var sides = definition.sides; // TODO: share this logic with GenerateCapsuleVertices var topHemisphere = definition.haveRoundedTop; var bottomHemisphere = definition.haveRoundedBottom; var topSegments = topHemisphere ? definition.topSegments : 0; var bottomSegments = bottomHemisphere ? definition.bottomSegments : 0; var extraVertices = definition.extraVertexCount; var bottomVertex = definition.bottomVertex; var topVertex = definition.topVertex; var rings = definition.ringCount; var bottomRing = (bottomHemisphere) ? (rings - bottomSegments) : rings - 1; var topRing = (topHemisphere) ? (topSegments - 1) : 0; var prevColor = UnityEditor.Handles.color; var color = prevColor; color.a *= 0.6f; for (int i = 0, j = extraVertices; i < rings; i++, j += sides) { if ((!definition.haveRoundedTop && i == topRing) || (!definition.haveRoundedBottom && i == bottomRing)) { continue; } bool isCapRing = (i == topRing || i == bottomRing); UnityEditor.Handles.color = (isCapRing ? prevColor : color); CSGOutlineRenderer.DrawLineLoop(vertices, j, sides, lineMode: lineMode, thickness: (isCapRing ? kCapLineThickness : kHorzLineThickness), dashSize: (isCapRing ? 0 : kLineDash)); } UnityEditor.Handles.color = color; for (int k = 0; k < sides; k++) { if (topHemisphere) { CSGOutlineRenderer.DrawLine(vertices[topVertex], vertices[extraVertices + k], lineMode: lineMode, thickness: kVertLineThickness); } for (int i = 0, j = extraVertices; i < rings - 1; i++, j += sides) { CSGOutlineRenderer.DrawLine(vertices[j + k], vertices[j + k + sides], lineMode: lineMode, thickness: kVertLineThickness); } if (bottomHemisphere) { CSGOutlineRenderer.DrawLine(vertices[bottomVertex], vertices[extraVertices + k + ((rings - 1) * sides)], lineMode: lineMode, thickness: kVertLineThickness); } } UnityEditor.Handles.color = prevColor; }
static void DrawOutline(CSGTorusDefinition definition, Vector3[] vertices, LineMode lineMode) { //var baseColor = UnityEditor.Handles.yAxisColor; //var isDisabled = UnitySceneExtensions.Handles.disabled; var normal = Vector3.up; var horzSegments = definition.horizontalSegments; var vertSegments = definition.verticalSegments; if (definition.totalAngle != 360) { horzSegments++; } var prevColor = UnityEditor.Handles.color; prevColor.a *= 0.8f; var color = prevColor; color.a *= 0.6f; UnityEditor.Handles.color = color; for (int i = 0, j = 0; i < horzSegments; i++, j += vertSegments) { CSGOutlineRenderer.DrawLineLoop(vertices, j, vertSegments, lineMode: lineMode, thickness: kVertLineThickness); } for (int k = 0; k < vertSegments; k++) { for (int i = 0, j = 0; i < horzSegments - 1; i++, j += vertSegments) { CSGOutlineRenderer.DrawLine(vertices[j + k], vertices[j + k + vertSegments], lineMode: lineMode, thickness: kHorzLineThickness); } } if (definition.totalAngle == 360) { for (int k = 0; k < vertSegments; k++) { CSGOutlineRenderer.DrawLine(vertices[k], vertices[k + ((horzSegments - 1) * vertSegments)], lineMode: lineMode, thickness: kHorzLineThickness); } } UnityEditor.Handles.color = prevColor; }
static void DrawOutline(CSGHemisphereDefinition definition, Vector3[] vertices, LineMode lineMode) { //var baseColor = UnityEditor.Handles.yAxisColor; //var isDisabled = UnitySceneExtensions.Handles.disabled; //var normal = Vector3.up; var sides = definition.horizontalSegments; var topSegments = Mathf.Max(definition.verticalSegments, 0); var bottomCap = false; var topCap = (topSegments != 0); var extraVertices = ((topCap) ? 1 : 0) + ((bottomCap) ? 1 : 0); var bottomVertex = 0; //var topVertex = (bottomCap) ? 1 : 0; var rings = (vertices.Length - extraVertices) / sides; var bottomRing = 0; var prevColor = UnityEditor.Handles.color; var color = prevColor; color.a *= 0.6f; for (int i = 0, j = extraVertices; i < rings; i++, j += sides) { UnityEditor.Handles.color = ((i == bottomRing) ? prevColor : color); CSGOutlineRenderer.DrawLineLoop(vertices, j, sides, lineMode: lineMode, thickness: ((i == bottomRing) ? kCapLineThickness : kHorzLineThickness), dashSize: ((i == bottomRing) ? 0 : kLineDash)); } UnityEditor.Handles.color = color; for (int k = 0; k < sides; k++) { for (int i = 0, j = extraVertices; i < rings - 1; i++, j += sides) { CSGOutlineRenderer.DrawLine(vertices[j + k], vertices[j + k + sides], lineMode: lineMode, thickness: kVertLineThickness); } if (topCap) { CSGOutlineRenderer.DrawLine(vertices[bottomVertex], vertices[extraVertices + k + ((rings - 1) * sides)], lineMode: lineMode, thickness: kVertLineThickness); } } UnityEditor.Handles.color = prevColor; }
static void DrawOutline(CSGStadiumDefinition definition, Vector3[] vertices, LineMode lineMode) { var sides = definition.sides; var topSides = Mathf.Max(definition.topSides, 1) + 1; var bottomSides = Mathf.Max(definition.bottomSides, 1) + 1; var haveRoundedTop = definition.haveRoundedTop; var haveRoundedBottom = definition.haveRoundedBottom; var haveCenter = definition.haveCenter; //CSGOutlineRenderer.DrawLineLoop(vertices, 0, sides, lineMode: lineMode, thickness: kCapLineThickness); //CSGOutlineRenderer.DrawLineLoop(vertices, sides, sides, lineMode: lineMode, thickness: kCapLineThickness); var firstTopSide = definition.firstTopSide; var lastTopSide = definition.lastTopSide; for (int k = firstTopSide; k <= lastTopSide; k++) { var sideLine = !haveRoundedTop || (k == firstTopSide) || (k == lastTopSide); var thickness = (sideLine ? kSideLineThickness : kVertLineThickness); var dashSize = (sideLine ? 0 : kLineDash); CSGOutlineRenderer.DrawLine(vertices[k], vertices[sides + k], lineMode: lineMode, thickness: thickness, dashSize: dashSize); } var firstBottomSide = definition.firstBottomSide; var lastBottomSide = definition.lastBottomSide; for (int k = firstBottomSide; k <= lastBottomSide; k++) { var sideLine = haveCenter && (!haveRoundedBottom || (k == firstBottomSide) || (k == lastBottomSide)); var thickness = (sideLine ? kSideLineThickness : kVertLineThickness); var dashSize = (sideLine ? 0 : kLineDash); CSGOutlineRenderer.DrawLine(vertices[k], vertices[sides + k], lineMode: lineMode, thickness: thickness, dashSize: dashSize); } //CSGOutlineRenderer.DrawLine(vertices[firstBottomSide], vertices[lastBottomSide], lineMode: lineMode, thickness: kVertLineThickness); //CSGOutlineRenderer.DrawLine(vertices[firstTopSide ], vertices[lastTopSide ], lineMode: lineMode, thickness: kVertLineThickness); //CSGOutlineRenderer.DrawLine(vertices[sides + firstBottomSide], vertices[sides + lastBottomSide], lineMode: lineMode, thickness: kVertLineThickness); //CSGOutlineRenderer.DrawLine(vertices[sides + firstTopSide ], vertices[sides + lastTopSide ], lineMode: lineMode, thickness: kVertLineThickness); }
protected override void OnScene(CSGBrush generator) { var targetBrushMeshAsset = generator.BrushMeshAsset; if (!targetBrushMeshAsset) { return; } EditorGUI.BeginChangeCheck(); var modelMatrix = CSGNodeHierarchyManager.FindModelTransformMatrixOfTransform(generator.hierarchyItem.Transform); var vertices = targetBrushMeshAsset.Vertices; var halfEdges = targetBrushMeshAsset.HalfEdges; //HashSet<CSGTreeBrush> foundBrushes = new HashSet<CSGTreeBrush>(); //targetBrush.GetAllTreeBrushes(foundBrushes, false) //foreach (var brush in CSGSyncSelection.GetSelectedVariantsOfBrushOrSelf((CSGTreeBrush)generator.TopNode)) { var brush = (CSGTreeBrush)generator.TopNode; var transformation = modelMatrix * brush.NodeToTreeSpaceMatrix; for (int e = 0; e < halfEdges.Length; e++) { var vertexIndex1 = halfEdges[e].vertexIndex; var vertexIndex2 = halfEdges[halfEdges[e].twinIndex].vertexIndex; var from = vertices[vertexIndex1]; var to = vertices[vertexIndex2]; CSGOutlineRenderer.DrawLine(transformation, from, to, UnityEditor.Handles.yAxisColor, thickness: 1.0f); } } //var newBounds = CSGHandles.BoundsHandle(originalBounds, Quaternion.identity, CSGHandles.DotHandleCap); if (EditorGUI.EndChangeCheck()) { //Undo.RecordObject(target, "Changed shape of Brush"); //brush.Bounds = newBounds; } }
protected override void OnScene(CSGRevolvedShape generator) { var baseColor = UnityEditor.Handles.yAxisColor; var isDisabled = UnitySceneExtensions.SceneHandles.disabled; var focusControl = UnitySceneExtensions.SceneHandleUtility.focusControl; var normal = Vector3.forward; var shape = generator.Shape; var controlPoints = shape.controlPoints; /* * for (int p0 = controlPoints.Length - 1, p1 = 0; p1 < controlPoints.Length; p0 = p1, p1++) * { * var point0 = controlPoints[p0].position; * var point1 = controlPoints[p1].position; * * } */ var shapeVertices = new List <Vector2>(); var shapeSegmentIndices = new List <int>(); BrushMeshAssetFactory.GetPathVertices(generator.definition.shape, generator.definition.curveSegments, shapeVertices, shapeSegmentIndices); var horzSegments = generator.definition.revolveSegments; var horzDegreePerSegment = generator.definition.totalAngle / horzSegments; var horzOffset = generator.definition.startAngle; var noZTestcolor = CSGCylinderEditor.GetColorForState(baseColor, false, true, isDisabled); var zTestcolor = CSGCylinderEditor.GetColorForState(baseColor, false, false, isDisabled); for (int h = 1, pr = 0; h < horzSegments + 1; pr = h, h++) { var hDegree0 = (pr * horzDegreePerSegment) + horzOffset; var hDegree1 = (h * horzDegreePerSegment) + horzOffset; var rotation0 = Quaternion.AngleAxis(hDegree0, normal); var rotation1 = Quaternion.AngleAxis(hDegree1, normal); for (int p0 = controlPoints.Length - 1, p1 = 0; p1 < controlPoints.Length; p0 = p1, p1++) { var point0 = controlPoints[p0].position; //var point1 = controlPoints[p1].position; var vertexA = rotation0 * new Vector3(point0.x, 0, point0.y); var vertexB = rotation1 * new Vector3(point0.x, 0, point0.y); //var vertexC = rotation0 * new Vector3(point1.x, 0, point1.y); UnityEditor.Handles.color = noZTestcolor; CSGOutlineRenderer.DrawLine(vertexA, vertexB, lineMode: LineMode.NoZTest, thickness: kHorzLineThickness);//, dashSize: kLineDash); UnityEditor.Handles.color = zTestcolor; CSGOutlineRenderer.DrawLine(vertexA, vertexB, lineMode: LineMode.ZTest, thickness: kHorzLineThickness); //, dashSize: kLineDash); } for (int v0 = shapeVertices.Count - 1, v1 = 0; v1 < shapeVertices.Count; v0 = v1, v1++) { var point0 = shapeVertices[v0]; var point1 = shapeVertices[v1]; var vertexA = rotation0 * new Vector3(point0.x, 0, point0.y); var vertexB = rotation0 * new Vector3(point1.x, 0, point1.y); UnityEditor.Handles.color = noZTestcolor; CSGOutlineRenderer.DrawLine(vertexA, vertexB, lineMode: LineMode.NoZTest, thickness: kHorzLineThickness, dashSize: kLineDash); UnityEditor.Handles.color = zTestcolor; CSGOutlineRenderer.DrawLine(vertexA, vertexB, lineMode: LineMode.ZTest, thickness: kHorzLineThickness, dashSize: kLineDash); } } EditorGUI.BeginChangeCheck(); { // TODO: make this work non grid aligned so we can place it upwards UnityEditor.Handles.color = baseColor; shape = UnitySceneExtensions.SceneHandles.Curve2DHandle(Matrix4x4.TRS(Vector3.zero, Quaternion.AngleAxis(90, Vector3.right), Vector3.one), shape); UnityEditor.Handles.DrawDottedLine(normal * 10, normal * -10, 4.0f); } if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(target, "Modified " + generator.NodeTypeName); generator.Shape = shape; } }
protected override void OnScene(CSGStadium generator) { var baseColor = UnityEditor.Handles.yAxisColor; var isDisabled = UnitySceneExtensions.SceneHandles.disabled; var focusControl = UnitySceneExtensions.SceneHandleUtility.focusControl; var upVector = Vector3.up; var rightVector = Vector3.right; var forwardVector = Vector3.forward; Vector3[] vertices = null; if (!BrushMeshAssetFactory.GenerateStadiumVertices(generator.definition, ref vertices)) { return; } UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, false, false, isDisabled); DrawOutline(generator.definition, vertices, lineMode: LineMode.ZTest); UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, false, true, isDisabled); DrawOutline(generator.definition, vertices, lineMode: LineMode.NoZTest); var height = generator.definition.height; var length = generator.definition.length; var diameter = generator.definition.diameter; var sides = generator.definition.sides; var firstTopSide = generator.definition.firstTopSide; var lastTopSide = generator.definition.lastTopSide; var firstBottomSide = generator.definition.firstBottomSide; var lastBottomSide = generator.definition.lastBottomSide; var haveRoundedTop = generator.definition.haveRoundedTop; var haveRoundedBottom = generator.definition.haveRoundedBottom; var haveCenter = generator.definition.haveCenter; var topLength = generator.definition.topLength; var bottomLength = generator.definition.bottomLength; var midY = height * 0.5f; var halfLength = length * 0.5f; var midZ = ((halfLength - (haveRoundedTop ? topLength : 0)) - (halfLength - (haveRoundedBottom ? bottomLength : 0))) * -0.5f; // haveCenter ? ((vertices[firstTopSide].z + vertices[firstBottomSide].z) * 0.5f) : 0; var topPoint = new Vector3(0, height, midZ); var bottomPoint = new Vector3(0, 0, midZ); var frontPoint = new Vector3(0, midY, halfLength); var backPoint = new Vector3(0, midY, -halfLength); var leftPoint = new Vector3(diameter * 0.5f, midY, midZ); var rightPoint = new Vector3(diameter * -0.5f, midY, midZ); EditorGUI.BeginChangeCheck(); { var topId = GUIUtility.GetControlID(s_TopHash, FocusType.Passive); { var isTopBackfaced = CSGCylinderEditor.IsSufaceBackFaced(topPoint, upVector); var topHasFocus = (focusControl == topId); UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, topHasFocus, isTopBackfaced, isDisabled); topPoint = UnitySceneExtensions.SceneHandles.DirectionHandle(topId, topPoint, upVector); //if (generator.definition.haveRoundedTop) { var thickness = topHasFocus ? kCapLineThicknessSelected : kCapLineThickness; UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, topHasFocus, true, isDisabled); CSGOutlineRenderer.DrawLineLoop(vertices, sides, sides, lineMode: LineMode.NoZTest, thickness: thickness); if (haveRoundedTop) { CSGOutlineRenderer.DrawLine(vertices[sides + firstTopSide], vertices[sides + lastTopSide], lineMode: LineMode.NoZTest, thickness: kVertLineThickness); } if (haveRoundedBottom && haveCenter) { CSGOutlineRenderer.DrawLine(vertices[sides + firstBottomSide], vertices[sides + lastBottomSide], lineMode: LineMode.NoZTest, thickness: kVertLineThickness); } UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, topHasFocus, false, isDisabled); CSGOutlineRenderer.DrawLineLoop(vertices, sides, sides, lineMode: LineMode.ZTest, thickness: thickness); if (haveRoundedTop) { CSGOutlineRenderer.DrawLine(vertices[sides + firstTopSide], vertices[sides + lastTopSide], lineMode: LineMode.ZTest, thickness: kVertLineThickness); } if (haveRoundedBottom && haveCenter) { CSGOutlineRenderer.DrawLine(vertices[sides + firstBottomSide], vertices[sides + lastBottomSide], lineMode: LineMode.ZTest, thickness: kVertLineThickness); } } } var bottomId = GUIUtility.GetControlID(s_BottomHash, FocusType.Passive); { var isBottomBackfaced = CSGCylinderEditor.IsSufaceBackFaced(bottomPoint, -upVector); var bottomHasFocus = (focusControl == bottomId); UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, bottomHasFocus, isBottomBackfaced, isDisabled); bottomPoint = UnitySceneExtensions.SceneHandles.DirectionHandle(bottomId, bottomPoint, -upVector); //if (haveRoundedBottom) { var thickness = bottomHasFocus ? kCapLineThicknessSelected : kCapLineThickness; UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, bottomHasFocus, true, isDisabled); CSGOutlineRenderer.DrawLineLoop(vertices, 0, sides, lineMode: LineMode.NoZTest, thickness: thickness); if (haveRoundedTop) { CSGOutlineRenderer.DrawLine(vertices[firstTopSide], vertices[lastTopSide], lineMode: LineMode.NoZTest, thickness: kVertLineThickness); } if (haveRoundedBottom && haveCenter) { CSGOutlineRenderer.DrawLine(vertices[firstBottomSide], vertices[lastBottomSide], lineMode: LineMode.NoZTest, thickness: kVertLineThickness); } UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, bottomHasFocus, false, isDisabled); CSGOutlineRenderer.DrawLineLoop(vertices, 0, sides, lineMode: LineMode.ZTest, thickness: thickness); if (haveRoundedTop) { CSGOutlineRenderer.DrawLine(vertices[firstTopSide], vertices[lastTopSide], lineMode: LineMode.ZTest, thickness: kVertLineThickness); } if (haveRoundedBottom && haveCenter) { CSGOutlineRenderer.DrawLine(vertices[firstBottomSide], vertices[lastBottomSide], lineMode: LineMode.ZTest, thickness: kVertLineThickness); } } } var frontId = GUIUtility.GetControlID(s_TopHash, FocusType.Passive); { var isTopBackfaced = CSGCylinderEditor.IsSufaceBackFaced(frontPoint, forwardVector); var frontHasFocus = (focusControl == frontId); UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, frontHasFocus, isTopBackfaced, isDisabled); frontPoint = UnitySceneExtensions.SceneHandles.DirectionHandle(frontId, frontPoint, forwardVector); } var backId = GUIUtility.GetControlID(s_BottomHash, FocusType.Passive); { var isBottomBackfaced = CSGCylinderEditor.IsSufaceBackFaced(backPoint, -forwardVector); var backHasFocus = (focusControl == backId); UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, backHasFocus, isBottomBackfaced, isDisabled); backPoint = UnitySceneExtensions.SceneHandles.DirectionHandle(backId, backPoint, -forwardVector); } var leftId = GUIUtility.GetControlID(s_TopHash, FocusType.Passive); { var isTopBackfaced = CSGCylinderEditor.IsSufaceBackFaced(leftPoint, rightVector); var leftHasFocus = (focusControl == leftId); UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, leftHasFocus, isTopBackfaced, isDisabled); leftPoint = UnitySceneExtensions.SceneHandles.DirectionHandle(leftId, leftPoint, rightVector); } var rightId = GUIUtility.GetControlID(s_BottomHash, FocusType.Passive); { var isBottomBackfaced = CSGCylinderEditor.IsSufaceBackFaced(rightPoint, -rightVector); var rightHasFocus = (focusControl == rightId); UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, rightHasFocus, isBottomBackfaced, isDisabled); rightPoint = UnitySceneExtensions.SceneHandles.DirectionHandle(rightId, rightPoint, -rightVector); } } if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(target, "Modified " + generator.NodeTypeName); generator.definition.height = topPoint.y - bottomPoint.y; generator.definition.length = Mathf.Max(0, frontPoint.z - backPoint.z); generator.definition.diameter = leftPoint.x - rightPoint.x; generator.OnValidate(); // TODO: handle sizing in some directions (needs to modify transformation?) } }
public void ShowInstance() { var tempTop = generator.Top; var tempBottom = generator.Bottom; var sides = generator.Sides; var topId = GUIUtility.GetControlID(s_TopHash, FocusType.Passive); var bottomId = GUIUtility.GetControlID(s_BottomHash, FocusType.Passive); var focusControl = UnitySceneExtensions.SceneHandleUtility.focusControl; var color = UnityEditor.Handles.yAxisColor; var isDisabled = UnitySceneExtensions.SceneHandles.disabled; if (!generator.IsEllipsoid) { tempTop.diameterZ = tempTop.diameterX; tempBottom.diameterZ = tempBottom.diameterX; } EditorGUI.BeginChangeCheck(); { switch (generator.Type) { case CylinderShapeType.Cylinder: { if (generator.IsEllipsoid) { UnitySceneExtensions.SceneHandles.Radius2DHandle(topPoint, normal, ref bottomXVector, ref bottomZVector, renderDisc: false); UnitySceneExtensions.SceneHandles.Radius2DHandle(bottomPoint, -normal, ref bottomXVector, ref bottomZVector, renderDisc: false); } else { bottomXVector = UnitySceneExtensions.SceneHandles.Radius2DHandle(topPoint, normal, bottomXVector, renderDisc: false); bottomXVector = UnitySceneExtensions.SceneHandles.Radius2DHandle(bottomPoint, -normal, bottomXVector, renderDisc: false); bottomZVector = bottomXVector; } topXVector = bottomXVector; topZVector = bottomZVector; tempTop.diameterX = tempBottom.diameterX; tempTop.diameterZ = tempBottom.diameterZ; break; } case CylinderShapeType.ConicalFrustum: { if (generator.IsEllipsoid) { UnitySceneExtensions.SceneHandles.Radius2DHandle(topPoint, normal, ref topXVector, ref topZVector, renderDisc: false); UnitySceneExtensions.SceneHandles.Radius2DHandle(bottomPoint, -normal, ref bottomXVector, ref bottomZVector, renderDisc: false); } else { UnitySceneExtensions.SceneHandles.Radius2DHandle(topPoint, normal, ref topXVector, ref topXVector, renderDisc: false); UnitySceneExtensions.SceneHandles.Radius2DHandle(bottomPoint, -normal, ref bottomXVector, ref bottomXVector, renderDisc: false); bottomXVector = UnitySceneExtensions.SceneHandles.Radius2DHandle(bottomPoint, -normal, bottomXVector, renderDisc: false); bottomZVector = bottomXVector; } break; } case CylinderShapeType.Cone: { if (generator.IsEllipsoid) { UnitySceneExtensions.SceneHandles.Radius2DHandle(bottomPoint, -normal, ref bottomXVector, ref bottomZVector, renderDisc: false); } else { bottomXVector = UnitySceneExtensions.SceneHandles.Radius2DHandle(bottomPoint, -normal, bottomXVector, renderDisc: false); bottomZVector = bottomXVector; } topXVector = bottomXVector; topZVector = bottomZVector; tempTop.diameterX = 0; tempTop.diameterZ = 0; break; } } // TODO: add cylinder horizon "side-lines" } if (EditorGUI.EndChangeCheck()) { topZVector.y = 0; topXVector.y = 0; bottomZVector.y = 0; bottomXVector.y = 0; Undo.RecordObject(generator, "Modified " + generator.NodeTypeName); if (!generator.IsEllipsoid) { if (prevBottomXVector != bottomXVector) { bottomZVector = Vector3.Cross(normal, bottomXVector.normalized) * bottomXVector.magnitude; } if (prevTopXVector != topXVector) { topZVector = Vector3.Cross(normal, topXVector.normalized) * topXVector.magnitude; } } if (prevTopXVector != topXVector) { generator.Rotation = Utilities.GeometryMath.SignedAngle(Vector3.right, topXVector.normalized, Vector3.up); } else if (prevBottomXVector != bottomXVector) { generator.Rotation = Utilities.GeometryMath.SignedAngle(Vector3.right, bottomXVector.normalized, Vector3.up); } if (generator.IsEllipsoid) { generator.BottomDiameterX = bottomXVector.magnitude * 2.0f; generator.BottomDiameterZ = bottomZVector.magnitude * 2.0f; generator.TopDiameterX = topXVector.magnitude * 2.0f; generator.TopDiameterZ = topZVector.magnitude * 2.0f; } else { if (prevBottomZVector != bottomZVector) { generator.BottomDiameterX = bottomZVector.magnitude * 2.0f; generator.BottomDiameterZ = bottomZVector.magnitude * 2.0f; } else { generator.BottomDiameterX = bottomXVector.magnitude * 2.0f; generator.BottomDiameterZ = bottomXVector.magnitude * 2.0f; } if (prevTopZVector != topZVector) { generator.TopDiameterX = topZVector.magnitude * 2.0f; generator.TopDiameterZ = topZVector.magnitude * 2.0f; } else { generator.TopDiameterX = topXVector.magnitude * 2.0f; generator.TopDiameterZ = topXVector.magnitude * 2.0f; } } } const float kLineDash = 2.0f; const float kLineThickness = 1.0f; const float kCircleThickness = 1.5f; const float kCapLineThickness = 2.0f; const float kCapLineThicknessSelected = 2.5f; const int kMaxOutlineSides = 32; const int kMinimumSides = 8; var baseColor = UnityEditor.Handles.yAxisColor; BrushMeshAssetFactory.GetConicalFrustumVertices(tempBottom, tempTop, generator.Rotation, sides, ref vertices); if (generator.TopHeight < generator.BottomHeight) { normal = -normal; } var isTopBackfaced = IsSufaceBackFaced(topPoint, normal); var topHasFocus = (focusControl == topId); var topThickness = topHasFocus ? kCapLineThicknessSelected : kCapLineThickness; var isBottomBackfaced = IsSufaceBackFaced(bottomPoint, -normal); var bottomHasFocus = (focusControl == bottomId); var bottomThickness = bottomHasFocus ? kCapLineThicknessSelected : kCapLineThickness; UnityEditor.Handles.color = GetColorForState(baseColor, bottomHasFocus, isBottomBackfaced, isDisabled); CSGOutlineRenderer.DrawLineLoop(vertices, 0, sides, thickness: bottomThickness); UnityEditor.Handles.color = GetColorForState(baseColor, topHasFocus, isTopBackfaced, isDisabled); CSGOutlineRenderer.DrawLineLoop(vertices, sides, sides, thickness: topThickness); UnityEditor.Handles.color = GetColorForState(baseColor, false, false, isDisabled); for (int i = 0; i < sides; i++) { CSGOutlineRenderer.DrawLine(vertices[i], vertices[i + sides], lineMode: LineMode.ZTest, thickness: kLineThickness); } UnityEditor.Handles.color = GetColorForState(baseColor, false, true, isDisabled); for (int i = 0; i < sides; i++) { CSGOutlineRenderer.DrawLine(vertices[i], vertices[i + sides], lineMode: LineMode.NoZTest, thickness: kLineThickness); } /* * var point0 = camera.WorldToScreenPoint(topPoint); * var direction = camera.ScreenToWorldPoint(point0 - Vector3.right); * var point1 = camera.WorldToScreenPoint(point0 - (direction * tempTop.diameterX)); * var size = Mathf.Max(point1.x - point0.x, point1.y - point0.y); */ // TODO: figure out how to reduce the sides of the circle depending on radius & distance int outlineSides = kMaxOutlineSides; if (sides <= kMinimumSides) { BrushMeshAssetFactory.GetConicalFrustumVertices(tempBottom, tempTop, generator.Rotation, outlineSides, ref dottedVertices); UnityEditor.Handles.color = GetColorForState(baseColor, topHasFocus, false, isDisabled); CSGOutlineRenderer.DrawLineLoop(dottedVertices, outlineSides, outlineSides, lineMode: LineMode.ZTest, thickness: kCircleThickness, dashSize: kLineDash); UnityEditor.Handles.color = GetColorForState(baseColor, topHasFocus, true, isDisabled); CSGOutlineRenderer.DrawLineLoop(dottedVertices, outlineSides, outlineSides, lineMode: LineMode.NoZTest, thickness: kCircleThickness, dashSize: kLineDash); UnityEditor.Handles.color = GetColorForState(baseColor, bottomHasFocus, false, isDisabled); CSGOutlineRenderer.DrawLineLoop(dottedVertices, 0, outlineSides, lineMode: LineMode.ZTest, thickness: kCircleThickness, dashSize: kLineDash); UnityEditor.Handles.color = GetColorForState(baseColor, bottomHasFocus, true, isDisabled); CSGOutlineRenderer.DrawLineLoop(dottedVertices, 0, outlineSides, lineMode: LineMode.NoZTest, thickness: kCircleThickness, dashSize: kLineDash); } EditorGUI.BeginChangeCheck(); { UnityEditor.Handles.color = GetColorForState(baseColor, bottomHasFocus, isBottomBackfaced, isDisabled); bottomPoint = UnitySceneExtensions.SceneHandles.DirectionHandle(bottomId, bottomPoint, -normal); UnityEditor.Handles.color = GetColorForState(baseColor, topHasFocus, isTopBackfaced, isDisabled); topPoint = UnitySceneExtensions.SceneHandles.DirectionHandle(topId, topPoint, normal); } if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(generator, "Modified " + generator.NodeTypeName); generator.TopHeight = Vector3.Dot(Vector3.up, topPoint); generator.BottomHeight = Vector3.Dot(Vector3.up, bottomPoint); } }
protected override void OnScene(CSGExtrudedShape generator) { var baseColor = UnityEditor.Handles.yAxisColor; var isDisabled = UnitySceneExtensions.SceneHandles.disabled; var focusControl = UnitySceneExtensions.SceneHandleUtility.focusControl; var normal = Vector3.forward; var noZTestcolor = CSGCylinderEditor.GetColorForState(baseColor, false, true, isDisabled); var zTestcolor = CSGCylinderEditor.GetColorForState(baseColor, false, false, isDisabled); /* * var shapeVertices2D = new List<Vector2>(); * var shapeSegmentIndices = new List<int>(); * BrushFactory.GetPathVertices(generator.Shape, generator.curveSegments, shapeVertices2D, shapeSegmentIndices); * * var shapeVertices3D = new Vector3[shapeVertices2D.Count]; * for (int v = 0; v < shapeVertices2D.Count; v++) * shapeVertices3D[v] = new Vector3(shapeVertices2D[v].x, shapeVertices2D[v].y, 0); */ var shape = generator.Shape; var path = generator.Path; var prevMatrix = UnityEditor.Handles.matrix; for (int i = 0; i < path.segments.Length; i++) { var pathPoint = path.segments[i]; var currMatrix = pathPoint.ToMatrix(); UnityEditor.Handles.color = baseColor; EditorGUI.BeginChangeCheck(); { shape = UnitySceneExtensions.SceneHandles.Curve2DHandle(currMatrix, shape);//, renderLines: false); } if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(target, "Modified " + generator.NodeTypeName); generator.Shape = shape; } //UnityEditor.Handles.color = noZTestcolor; //CSGOutlineRenderer.DrawLineLoop(prevMatrix * currMatrix, shapeVertices3D, 0, shapeVertices3D.Length, lineMode: LineMode.NoZTest, thickness: kCapLineThickness); //UnityEditor.Handles.color = zTestcolor; //CSGOutlineRenderer.DrawLineLoop(prevMatrix * currMatrix, shapeVertices3D, 0, shapeVertices3D.Length, lineMode: LineMode.ZTest, thickness: kCapLineThickness); // Draw lines between different segments if (i + 1 < path.segments.Length) { var nextPoint = path.segments[i + 1]; var nextMatrix = nextPoint.ToMatrix(); var controlPoints = shape.controlPoints; for (int c = 0; c < controlPoints.Length; c++) { var controlPoint = controlPoints[c].position; var pointA = currMatrix.MultiplyPoint(controlPoint); var pointB = nextMatrix.MultiplyPoint(controlPoint); UnityEditor.Handles.color = noZTestcolor; CSGOutlineRenderer.DrawLine(pointA, pointB, lineMode: LineMode.NoZTest, thickness: kCapLineThickness, dashSize: kLineDash); UnityEditor.Handles.color = zTestcolor; CSGOutlineRenderer.DrawLine(pointA, pointB, lineMode: LineMode.ZTest, thickness: kCapLineThickness, dashSize: kLineDash); } { var pointA = currMatrix.MultiplyPoint(Vector3.zero); var pointB = nextMatrix.MultiplyPoint(Vector3.zero); UnityEditor.Handles.color = zTestcolor; CSGOutlineRenderer.DrawLine(pointA, pointB, lineMode: LineMode.NoZTest, thickness: kCapLineThickness, dashSize: kLineDash); UnityEditor.Handles.color = zTestcolor; CSGOutlineRenderer.DrawLine(pointA, pointB, lineMode: LineMode.ZTest, thickness: kCapLineThickness, dashSize: kLineDash); } UnityEditor.Handles.color = baseColor; } // TODO: cannot rotate so far that one path plane intersects with shape on another plane // ... or just fail when it's wrong? } for (int i = 0; i < path.segments.Length; i++) { var pathPoint = path.segments[i]; EditorGUI.BeginChangeCheck(); { switch (Tools.current) { case Tool.Move: { pathPoint.position = UnitySceneExtensions.SceneHandles.PositionHandle(pathPoint.position, pathPoint.rotation); break; } case Tool.Rotate: { if (Event.current.type == EventType.Repaint) { UnitySceneExtensions.SceneHandles.OutlinedDotHandleCap(0, pathPoint.position, pathPoint.rotation, UnityEditor.HandleUtility.GetHandleSize(pathPoint.position) * 0.05f, Event.current.type); } pathPoint.rotation = UnityEditor.Handles.RotationHandle(pathPoint.rotation, pathPoint.position); break; } case Tool.Scale: { var scale2D = pathPoint.scale; // TODO: create a 2D planar/bounds scale handle var scale3D = UnityEditor.Handles.ScaleHandle(new Vector3(scale2D.x, 1, scale2D.y), pathPoint.position, pathPoint.rotation, UnityEditor.HandleUtility.GetHandleSize(pathPoint.position)); pathPoint.scale = new Vector2(scale3D.x, scale3D.z); } break; } } if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(target, "Changed path of CSGShape"); var originalSegments = generator.Path.segments; path = new Path(new PathPoint[originalSegments.Length]); Array.Copy(originalSegments, path.segments, originalSegments.Length); path.segments[i] = pathPoint; generator.Path = path; } } // TODO: draw curved path }