public override void OnMouseUp(MouseEventArgs mouseEvent)
		{
			if (meshViewerWidget.TrackballTumbleWidget.TransformState == TrackBallController.MouseDownType.None
				&& meshSelectInfo.downOnPart
				&& meshSelectInfo.lastMoveDelta != Vector3.Zero)
			{
				PartHasBeenChanged();
			}

			meshSelectInfo.downOnPart = false;

			if (activeButtonBeforeMouseOverride != null)
			{
				viewControls3D.ActiveButton = (ViewControls3DButtons)activeButtonBeforeMouseOverride;
				activeButtonBeforeMouseOverride = null;
			}

			base.OnMouseUp(mouseEvent);
		}
		public override void OnMouseDown(MouseEventArgs mouseEvent)
		{
			// Show transform override
			if (activeButtonBeforeMouseOverride == null && mouseEvent.Button == MouseButtons.Right)
			{
				activeButtonBeforeMouseOverride = viewControls3D.ActiveButton;
				viewControls3D.ActiveButton = ViewControls3DButtons.Rotate;
			}
			else if (activeButtonBeforeMouseOverride == null && mouseEvent.Button == MouseButtons.Middle)
			{
				activeButtonBeforeMouseOverride = viewControls3D.ActiveButton;
				viewControls3D.ActiveButton = ViewControls3DButtons.Translate;
			}

			autoRotating = false;
			base.OnMouseDown(mouseEvent);
			if (meshViewerWidget.TrackballTumbleWidget.UnderMouseState == Agg.UI.UnderMouseState.FirstUnderMouse)
			{
				if (meshViewerWidget.TrackballTumbleWidget.TransformState == TrackBallController.MouseDownType.None
					&& mouseEvent.Button == MouseButtons.Left
					&& ModifierKeys != Keys.Shift
					&& ModifierKeys != Keys.Control
					&& ModifierKeys != Keys.Alt)
				{
					if (!meshViewerWidget.MouseDownOnInteractionVolume)
					{
						int meshGroupHitIndex;
						if (FindMeshGroupHitPosition(mouseEvent.Position, out meshGroupHitIndex))
						{
							meshSelectInfo.hitPlane = new PlaneShape(Vector3.UnitZ, meshSelectInfo.planeDownHitPos.z, null);
							SelectedMeshGroupIndex = meshGroupHitIndex;

							transformOnMouseDown = SelectedMeshGroupTransform.translation;

							Invalidate();
							meshSelectInfo.downOnPart = true;
						}
						else
						{
							SelectedMeshGroupIndex = -1;
						}

						UpdateSizeInfo();
					}
				}
			}
		}
		public override void OnKeyUp(KeyEventArgs keyEvent)
		{
			if (activeButtonBeforeKeyOverride != null)
			{
				viewControls3D.ActiveButton = (ViewControls3DButtons)activeButtonBeforeKeyOverride;
				activeButtonBeforeKeyOverride = null;
			}

			base.OnKeyUp(keyEvent);
		}
		public override void OnKeyDown(KeyEventArgs keyEvent)
		{
			if (activeButtonBeforeKeyOverride == null)
			{
				activeButtonBeforeKeyOverride = viewControls3D.ActiveButton;

				if (keyEvent.Alt)
				{
					viewControls3D.ActiveButton = ViewControls3DButtons.Rotate;
				}
				else if (keyEvent.Shift)
				{
					viewControls3D.ActiveButton = ViewControls3DButtons.Translate;
				}
				else if (keyEvent.Control)
				{
					viewControls3D.ActiveButton = ViewControls3DButtons.Scale;
				}
			}

			base.OnKeyDown(keyEvent);
		}
		public override void OnMouseDown(MouseEventArgs mouseEvent)
		{
			// Show transform override
			if (activeButtonBeforeMouseOverride == null && mouseEvent.Button == MouseButtons.Right)
			{
				activeButtonBeforeMouseOverride = viewControls3D.ActiveButton;
				viewControls3D.ActiveButton = ViewControls3DButtons.Rotate;
			}
			else if (activeButtonBeforeMouseOverride == null && mouseEvent.Button == MouseButtons.Middle)
			{
				activeButtonBeforeMouseOverride = viewControls3D.ActiveButton;
				viewControls3D.ActiveButton = ViewControls3DButtons.Translate;
			}

			autoRotating = false;
			base.OnMouseDown(mouseEvent);
			if (meshViewerWidget.TrackballTumbleWidget.UnderMouseState == Agg.UI.UnderMouseState.FirstUnderMouse)
			{
				if (meshViewerWidget.TrackballTumbleWidget.TransformState == TrackBallController.MouseDownType.None
					&& mouseEvent.Button == MouseButtons.Left
					&& ModifierKeys != Keys.Shift
					&& ModifierKeys != Keys.Control
					&& ModifierKeys != Keys.Alt)
				{
					if (!meshViewerWidget.MouseDownOnInteractionVolume)
					{
						int meshGroupHitIndex;
						IntersectInfo info = new IntersectInfo();
						if (FindMeshGroupHitPosition(mouseEvent.Position, out meshGroupHitIndex, ref info))
						{
							CurrentSelectInfo.HitPlane = new PlaneShape(Vector3.UnitZ, CurrentSelectInfo.PlaneDownHitPos.z, null);
							SelectedMeshGroupIndex = meshGroupHitIndex;

							transformOnMouseDown = SelectedMeshGroupTransform;

							Invalidate();
							CurrentSelectInfo.DownOnPart = true;

							AxisAlignedBoundingBox selectedBounds = meshViewerWidget.GetBoundsForSelection();

							if (info.hitPosition.x < selectedBounds.Center.x)
							{
								if (info.hitPosition.y < selectedBounds.Center.y)
								{
									CurrentSelectInfo.HitQuadrant = HitQuadrant.LB;
								}
								else
								{
									CurrentSelectInfo.HitQuadrant = HitQuadrant.LT;
								}
							}
							else
							{
								if (info.hitPosition.y < selectedBounds.Center.y)
								{
									CurrentSelectInfo.HitQuadrant = HitQuadrant.RB;
								}
								else
								{
									CurrentSelectInfo.HitQuadrant = HitQuadrant.RT;
								}
							}
						}
						else
						{
							SelectedMeshGroupIndex = -1;
						}

						SelectedTransformChanged?.Invoke(this, null);
					}
				}
			}
		}
		public override void OnMouseUp(MouseEventArgs mouseEvent)
		{
			if (meshViewerWidget.TrackballTumbleWidget.TransformState == TrackBallController.MouseDownType.None
				&& CurrentSelectInfo.DownOnPart
				&& CurrentSelectInfo.LastMoveDelta != Vector3.Zero)
			{
				if (SelectedMeshGroupTransform != transformOnMouseDown)
				{
					AddUndoForSelectedMeshGroupTransform(transformOnMouseDown);
					PartHasBeenChanged();
				}
			}

			CurrentSelectInfo.DownOnPart = false;

			if (activeButtonBeforeMouseOverride != null)
			{
				viewControls3D.ActiveButton = (ViewControls3DButtons)activeButtonBeforeMouseOverride;
				activeButtonBeforeMouseOverride = null;
			}

			base.OnMouseUp(mouseEvent);
		}