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?) } }
static Vector3[] vertices = null; // TODO: store this per instance? or just allocate every frame? protected override void OnScene(CSGCapsule generator) { var baseColor = UnityEditor.Handles.yAxisColor; var isDisabled = UnitySceneExtensions.SceneHandles.disabled; var focusControl = UnitySceneExtensions.SceneHandleUtility.focusControl; var normal = Vector3.up; if (!BrushMeshAssetFactory.GenerateCapsuleVertices(ref 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 topPoint = normal * (generator.definition.offsetY + generator.Height); var bottomPoint = normal * (generator.definition.offsetY); var middlePoint = normal * (generator.definition.offsetY + (generator.Height * 0.5f)); var radius2D = new Vector2(generator.definition.diameterX, generator.definition.diameterZ) * 0.5f; if (generator.Height < 0) { normal = -normal; } EditorGUI.BeginChangeCheck(); { UnityEditor.Handles.color = baseColor; // TODO: make it possible to (optionally) size differently in x & z radius2D.x = UnitySceneExtensions.SceneHandles.RadiusHandle(normal, middlePoint, radius2D.x); var topId = GUIUtility.GetControlID(s_TopHash, FocusType.Passive); { var isTopBackfaced = CSGCylinderEditor.IsSufaceBackFaced(topPoint, normal); var topHasFocus = (focusControl == topId); UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, topHasFocus, isTopBackfaced, isDisabled); topPoint = UnitySceneExtensions.SceneHandles.DirectionHandle(topId, topPoint, normal); if (!generator.HaveRoundedTop) { //var roundedTopPoint = normal * generator.definition.topOffset; var thickness = topHasFocus ? kCapLineThicknessSelected : kCapLineThickness; UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, topHasFocus, true, isDisabled); CSGOutlineRenderer.DrawLineLoop(vertices, generator.definition.topVertexOffset, generator.definition.sides, lineMode: LineMode.NoZTest, thickness: thickness); UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, topHasFocus, false, isDisabled); CSGOutlineRenderer.DrawLineLoop(vertices, generator.definition.topVertexOffset, generator.definition.sides, lineMode: LineMode.ZTest, thickness: thickness); } } var bottomId = GUIUtility.GetControlID(s_BottomHash, FocusType.Passive); { var isBottomBackfaced = CSGCylinderEditor.IsSufaceBackFaced(bottomPoint, -normal); var bottomHasFocus = (focusControl == bottomId); UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, bottomHasFocus, isBottomBackfaced, isDisabled); bottomPoint = UnitySceneExtensions.SceneHandles.DirectionHandle(bottomId, bottomPoint, -normal); if (!generator.HaveRoundedBottom) { //var roundedBottomPoint = normal * generator.definition.bottomOffset; var thickness = bottomHasFocus ? kCapLineThicknessSelected : kCapLineThickness; UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, bottomHasFocus, true, isDisabled); CSGOutlineRenderer.DrawLineLoop(vertices, generator.definition.bottomVertexOffset, generator.definition.sides, lineMode: LineMode.NoZTest, thickness: thickness); UnityEditor.Handles.color = CSGCylinderEditor.GetColorForState(baseColor, bottomHasFocus, false, isDisabled); CSGOutlineRenderer.DrawLineLoop(vertices, generator.definition.bottomVertexOffset, generator.definition.sides, lineMode: LineMode.ZTest, thickness: thickness); } } } if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(target, "Modified " + generator.NodeTypeName); generator.definition.diameterX = radius2D.x * 2.0f; generator.definition.height = topPoint.y - bottomPoint.y; generator.definition.diameterZ = radius2D.x * 2.0f; generator.definition.offsetY = bottomPoint.y; generator.OnValidate(); // TODO: handle sizing down (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); } }