public override async void OnMouseMove(Mouse3DEventArgs mouseEvent3D, bool mouseIsOver) { var selectedItem = RootSelection; ActiveSelectedItem = selectedItem; if (MouseIsOver || MouseDownOnControl) { diameterValueDisplayInfo.Visible = true; } else if (!hadClickOnControl || scaleController.HasChange) { diameterValueDisplayInfo.Visible = false; } if (MouseDownOnControl && hitPlane != null) { var info = hitPlane.GetClosestIntersection(mouseEvent3D.MouseRay); if (info != null && selectedItem != null) { var delta = info.HitPosition - initialHitPosition; var lockedBottomCenter = ObjectSpace.GetCenterPosition(selectedItem, placement); var(hit, otherSide) = GetHitIndices(selectedItem); var grabPositionEdge = ObjectSpace.GetEdgePosition(selectedItem, otherSide); var stretchDirection = (ObjectSpace.GetEdgePosition(selectedItem, hit) - grabPositionEdge).GetNormal(); var deltaAlongStretch = stretchDirection.Dot(delta); // scale it var newSize = scaleController.InitialState.Diameters[diameterIndex]; newSize += deltaAlongStretch * 2; newSize = Math.Max(Math.Max(newSize, .001), Object3DControlContext.SnapGridDistance); if (Object3DControlContext.SnapGridDistance > 0) { // snap this position to the grid double snapGridDistance = Object3DControlContext.SnapGridDistance; // snap this position to the grid newSize = ((int)((newSize / snapGridDistance) + .5)) * snapGridDistance; } scaleController.ScaleDiameter(newSize, diameterIndex); await selectedItem.Rebuild(); // and keep the locked edge in place Vector3 newBottomCenter = ObjectSpace.GetCenterPosition(selectedItem, placement); selectedItem.Matrix *= Matrix4X4.CreateTranslation(lockedBottomCenter - newBottomCenter); Invalidate(); } } base.OnMouseMove(mouseEvent3D, mouseIsOver); }
public override void Draw(DrawGlContentEventArgs e) { bool shouldDrawScaleControls = controlVisible == null ? true : controlVisible(); if (Object3DControlContext.SelectedObject3DControl != null && Object3DControlContext.SelectedObject3DControl as ScaleDiameterControl == null) { shouldDrawScaleControls = false; } var selectedItem = RootSelection; if (selectedItem != null) { // Ensures that functions in this scope run against the original instance reference rather than the // current value, thus avoiding null reference errors that would occur otherwise if (shouldDrawScaleControls) { // don't draw if any other control is dragging var color = theme.PrimaryAccentColor.WithAlpha(e.Alpha0to255); if (MouseIsOver || MouseDownOnControl) { GLHelper.Render(grabControlMesh, color, TotalTransform, RenderTypes.Shaded); } else { color = theme.TextColor; GLHelper.Render(grabControlMesh, color.WithAlpha(e.Alpha0to255), TotalTransform, RenderTypes.Shaded); } Vector3 newBottomCenter = ObjectSpace.GetCenterPosition(selectedItem, placement); var rotation = Matrix4X4.CreateRotation(new Quaternion(selectedItem.Matrix)); var translation = Matrix4X4.CreateTranslation(newBottomCenter); Object3DControlContext.World.RenderRing(rotation * translation, Vector3.Zero, getDiameters[diameterIndex](), 60, color.WithAlpha(e.Alpha0to255), 2, 0, e.ZBuffered); } if (hitPlane != null) { //Object3DControlContext.World.RenderPlane(hitPlane.Plane, Color.Red, true, 50, 3); //Object3DControlContext.World.RenderPlane(initialHitPosition, hitPlane.Plane.Normal, Color.Red, true, 50, 3); } if (shouldDrawScaleControls && (MouseIsOver || MouseDownOnControl)) { DrawMeasureLines(e); } } base.Draw(e); }
public ScaleDiameterControl(IObject3DControlContext context, Func <double> getHeight, Action <double> setHeight, List <Func <double> > getDiameters, List <Action <double> > setDiameters, int diameterIndex, ObjectSpace.Placement placement = ObjectSpace.Placement.Bottom, Func <bool> controlVisible = null, double angleOffset = 0) : base(context) { this.getHeight = getHeight; this.setHeight = setHeight; this.getDiameters = getDiameters; this.setDiameters = setDiameters; this.controlVisible = controlVisible; this.placement = placement; this.diameterIndex = diameterIndex; this.angleOffset = angleOffset; theme = MatterControl.AppContext.Theme; scaleController = new ScaleController(Object3DControlContext, null, null, null, null, getHeight, setHeight, getDiameters, setDiameters); diameterValueDisplayInfo = new InlineEditControl() { ForceHide = ForceHideScale, GetDisplayString = (value) => "{0:0.0}".FormatWith(value), }; diameterValueDisplayInfo.EditComplete += async(s, e) => { var newDiameter = diameterValueDisplayInfo.Value != 0 ? diameterValueDisplayInfo.Value : getDiameters[diameterIndex](); if (newDiameter == scaleController.FinalState.Diameters[diameterIndex]) { return; } Vector3 lockedEdge = ObjectSpace.GetCenterPosition(ActiveSelectedItem, placement); scaleController.ScaleDiameter(newDiameter, diameterIndex); await ActiveSelectedItem.Rebuild(); // and keep the locked edge in place Vector3 newLockedEdge = ObjectSpace.GetCenterPosition(ActiveSelectedItem, placement); ActiveSelectedItem.Translate(lockedEdge - newLockedEdge); scaleController.EditComplete(); scaleController = new ScaleController(Object3DControlContext, null, null, null, null, getHeight, setHeight, getDiameters, setDiameters); }; diameterValueDisplayInfo.VisibleChanged += (s, e) => { if (!diameterValueDisplayInfo.Visible) { hadClickOnControl = false; } }; Object3DControlContext.GuiSurface.AddChild(diameterValueDisplayInfo); DrawOnTop = true; grabControlMesh = SphereObject3D.CreateSphere(grabControlSize, 15, 10); CollisionVolume = grabControlMesh.CreateBVHData(); Object3DControlContext.GuiSurface.BeforeDraw += Object3DControl_BeforeDraw; }