static Vector3[] vertices = null; // TODO: store this per instance? or just allocate every frame? public void OnEdit(IChiselHandles handles) { var baseColor = handles.color; var normal = Vector3.up; if (BrushMeshFactory.GenerateCapsuleVertices(ref this, ref vertices)) { handles.color = handles.GetStateColor(baseColor, false, false); DrawOutline(handles, this, vertices, lineMode: LineMode.ZTest); handles.color = handles.GetStateColor(baseColor, false, true); DrawOutline(handles, this, vertices, lineMode: LineMode.NoZTest); handles.color = baseColor; } var topPoint = normal * (this.offsetY + this.height); var bottomPoint = normal * (this.offsetY); var middlePoint = normal * (this.offsetY + (this.height * 0.5f)); var radius2D = new Vector2(this.diameterX, this.diameterZ) * 0.5f; var topHeight = this.topHeight; var bottomHeight = this.bottomHeight; var maxTopHeight = this.height - bottomHeight; var maxBottomHeight = this.height - topHeight; if (this.height < 0) { normal = -normal; } var prevModified = handles.modified; { handles.color = baseColor; // TODO: make it possible to (optionally) size differently in x & z var radius2Dx = radius2D.x; handles.DoRadiusHandle(ref radius2Dx, normal, middlePoint); radius2D.x = radius2Dx; { var isTopBackfaced = handles.IsSufaceBackFaced(topPoint, normal); var topLoopHasFocus = false; handles.backfaced = isTopBackfaced; for (int j = this.sides - 1, i = 0; i < this.sides; j = i, i++) { var from = vertices[j + this.topVertexOffset]; var to = vertices[i + this.topVertexOffset]; if (handles.DoEdgeHandle1DOffset(out var edgeOffset, UnitySceneExtensions.Axis.Y, from, to, renderLine: false)) { topHeight = Mathf.Clamp(topHeight - edgeOffset, 0, maxTopHeight); } topLoopHasFocus = topLoopHasFocus || handles.lastHandleHadFocus; } handles.color = baseColor; handles.DoDirectionHandle(ref topPoint, normal); var topHasFocus = handles.lastHandleHadFocus; handles.backfaced = false; topLoopHasFocus = topLoopHasFocus || (topHasFocus && !this.haveRoundedTop); var thickness = topLoopHasFocus ? kCapLineThicknessSelected : kCapLineThickness; handles.color = handles.GetStateColor(baseColor, topLoopHasFocus, true); handles.DrawLineLoop(vertices, this.topVertexOffset, this.sides, lineMode: LineMode.NoZTest, thickness: thickness); handles.color = handles.GetStateColor(baseColor, topLoopHasFocus, false); handles.DrawLineLoop(vertices, this.topVertexOffset, this.sides, lineMode: LineMode.ZTest, thickness: thickness); } { var isBottomBackfaced = handles.IsSufaceBackFaced(bottomPoint, -normal); var bottomLoopHasFocus = false; handles.backfaced = isBottomBackfaced; for (int j = this.sides - 1, i = 0; i < this.sides; j = i, i++) { var from = vertices[j + this.bottomVertexOffset]; var to = vertices[i + this.bottomVertexOffset]; if (handles.DoEdgeHandle1DOffset(out var edgeOffset, UnitySceneExtensions.Axis.Y, from, to, renderLine: false)) { bottomHeight = Mathf.Clamp(bottomHeight + edgeOffset, 0, maxBottomHeight); } bottomLoopHasFocus = bottomLoopHasFocus || handles.lastHandleHadFocus; } handles.color = baseColor; handles.DoDirectionHandle(ref bottomPoint, -normal); var bottomHasFocus = handles.lastHandleHadFocus; handles.backfaced = false; bottomLoopHasFocus = bottomLoopHasFocus || (bottomHasFocus && !this.haveRoundedBottom); var thickness = bottomLoopHasFocus ? kCapLineThicknessSelected : kCapLineThickness; handles.color = handles.GetStateColor(baseColor, bottomLoopHasFocus, true); handles.DrawLineLoop(vertices, this.bottomVertexOffset, this.sides, lineMode: LineMode.NoZTest, thickness: thickness); handles.color = handles.GetStateColor(baseColor, bottomLoopHasFocus, false); handles.DrawLineLoop(vertices, this.bottomVertexOffset, this.sides, lineMode: LineMode.ZTest, thickness: thickness); } } if (prevModified != handles.modified) { this.diameterX = radius2D.x * 2.0f; this.height = topPoint.y - bottomPoint.y; this.diameterZ = radius2D.x * 2.0f; this.offsetY = bottomPoint.y; this.topHeight = topHeight; this.bottomHeight = bottomHeight; // TODO: handle sizing down (needs to modify transformation?) } }
public void OnEdit(IChiselHandles handles) { var baseColor = handles.color; var upVector = Vector3.up; var rightVector = Vector3.right; var forwardVector = Vector3.forward; Vector3[] vertices = null; if (BrushMeshFactory.GenerateStadiumVertices(this, ref vertices)) { handles.color = handles.GetStateColor(baseColor, false, false); DrawOutline(handles, this, vertices, lineMode: LineMode.ZTest); handles.color = handles.GetStateColor(baseColor, false, true); DrawOutline(handles, this, vertices, lineMode: LineMode.NoZTest); handles.color = baseColor; } var height = this.height; var length = this.length; var diameter = this.diameter; var sides = this.sides; var firstTopSide = this.firstTopSide; var lastTopSide = this.lastTopSide; var firstBottomSide = this.firstBottomSide; var lastBottomSide = this.lastBottomSide; var haveRoundedTop = this.haveRoundedTop; var haveRoundedBottom = this.haveRoundedBottom; var haveCenter = this.haveCenter; var topLength = this.topLength; var bottomLength = this.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); { { var isTopBackfaced = handles.IsSufaceBackFaced(topPoint, upVector); handles.backfaced = isTopBackfaced; handles.DoDirectionHandle(ref topPoint, upVector); var topHasFocus = handles.lastHandleHadFocus; handles.backfaced = false; //if (this.haveRoundedTop) { var thickness = topHasFocus ? kCapLineThicknessSelected : kCapLineThickness; handles.color = handles.GetStateColor(handles.color, topHasFocus, true); handles.DrawLineLoop(vertices, sides, sides, lineMode: LineMode.NoZTest, thickness: thickness); if (haveRoundedTop) { handles.DrawLine(vertices[sides + firstTopSide], vertices[sides + lastTopSide], lineMode: LineMode.NoZTest, thickness: kVertLineThickness); } if (haveRoundedBottom && haveCenter) { handles.DrawLine(vertices[sides + firstBottomSide], vertices[sides + lastBottomSide], lineMode: LineMode.NoZTest, thickness: kVertLineThickness); } handles.color = handles.GetStateColor(handles.color, topHasFocus, false); handles.DrawLineLoop(vertices, sides, sides, lineMode: LineMode.ZTest, thickness: thickness); if (haveRoundedTop) { handles.DrawLine(vertices[sides + firstTopSide], vertices[sides + lastTopSide], lineMode: LineMode.ZTest, thickness: kVertLineThickness); } if (haveRoundedBottom && haveCenter) { handles.DrawLine(vertices[sides + firstBottomSide], vertices[sides + lastBottomSide], lineMode: LineMode.ZTest, thickness: kVertLineThickness); } } } { var isBottomBackfaced = handles.IsSufaceBackFaced(bottomPoint, -upVector); handles.backfaced = isBottomBackfaced; handles.DoDirectionHandle(ref bottomPoint, -upVector); var bottomHasFocus = handles.lastHandleHadFocus; handles.backfaced = false; //if (this.haveRoundedBottom) { var thickness = bottomHasFocus ? kCapLineThicknessSelected : kCapLineThickness; handles.color = handles.GetStateColor(baseColor, bottomHasFocus, true); handles.DrawLineLoop(vertices, 0, sides, lineMode: LineMode.NoZTest, thickness: thickness); if (haveRoundedTop) { handles.DrawLine(vertices[firstTopSide], vertices[lastTopSide], lineMode: LineMode.NoZTest, thickness: kVertLineThickness); } if (haveRoundedBottom && haveCenter) { handles.DrawLine(vertices[firstBottomSide], vertices[lastBottomSide], lineMode: LineMode.NoZTest, thickness: kVertLineThickness); } handles.color = handles.GetStateColor(baseColor, bottomHasFocus, false); handles.DrawLineLoop(vertices, 0, sides, lineMode: LineMode.ZTest, thickness: thickness); if (haveRoundedTop) { handles.DrawLine(vertices[firstTopSide], vertices[lastTopSide], lineMode: LineMode.ZTest, thickness: kVertLineThickness); } if (haveRoundedBottom && haveCenter) { handles.DrawLine(vertices[firstBottomSide], vertices[lastBottomSide], lineMode: LineMode.ZTest, thickness: kVertLineThickness); } } } { var isTopBackfaced = handles.IsSufaceBackFaced(frontPoint, forwardVector); handles.backfaced = isTopBackfaced; handles.DoDirectionHandle(ref frontPoint, forwardVector); handles.backfaced = false; } { var isBottomBackfaced = handles.IsSufaceBackFaced(backPoint, -forwardVector); handles.backfaced = isBottomBackfaced; handles.DoDirectionHandle(ref backPoint, -forwardVector); handles.backfaced = false; } { var isTopBackfaced = handles.IsSufaceBackFaced(leftPoint, rightVector); handles.backfaced = isTopBackfaced; handles.DoDirectionHandle(ref leftPoint, rightVector); handles.backfaced = false; } { var isBottomBackfaced = handles.IsSufaceBackFaced(rightPoint, -rightVector); handles.backfaced = isBottomBackfaced; handles.DoDirectionHandle(ref rightPoint, -rightVector); handles.backfaced = false; } } if (handles.modified) { this.height = topPoint.y - bottomPoint.y; this.length = Mathf.Max(0, frontPoint.z - backPoint.z); this.diameter = leftPoint.x - rightPoint.x; // TODO: handle sizing in some directions (needs to modify transformation?) } }