private (int edge, int otherSide) GetHitIndices(IObject3D selectedItem) { var bestZEdgePosition = -1; var otherSide = -1; var bestCornerZ = double.PositiveInfinity; // get the closest z on the bottom in view space for (int i = 0; i < 4; i++) { Vector3 cornerPosition = ObjectSpace.GetEdgePosition(selectedItem, i, placement); Vector3 cornerScreenSpace = Object3DControlContext.World.WorldToScreenSpace(cornerPosition); if (cornerScreenSpace.Z < bestCornerZ) { bestCornerZ = cornerScreenSpace.Z; bestZEdgePosition = i; otherSide = (i + 2) % 4; } } return(bestZEdgePosition, otherSide); }
private Vector3 GetDeltaToOtherSideXy(IObject3D selectedItem, int quadrantIndex) { Vector3 cornerPosition = ObjectSpace.GetCornerPosition(selectedItem, quadrantIndex); Vector3 cornerPositionCcw = ObjectSpace.GetCornerPosition(selectedItem, quadrantIndex + 1); Vector3 cornerPositionCw = ObjectSpace.GetCornerPosition(selectedItem, quadrantIndex + 3); double xDirection = cornerPositionCcw.X - cornerPosition.X; if (xDirection == 0) { xDirection = cornerPositionCw.X - cornerPosition.X; } double yDirection = cornerPositionCcw.Y - cornerPosition.Y; if (yDirection == 0) { yDirection = cornerPositionCw.Y - cornerPosition.Y; } return(new Vector3(xDirection, yDirection, cornerPosition.Z)); }
public override void SetPosition(IObject3D selectedItem, MeshSelectInfo selectInfo) { // create the transform for the box Vector3 edgePosition = ObjectSpace.GetEdgePosition(selectedItem, edgeIndex); Vector3 boxCenter = edgePosition; double distBetweenPixelsWorldSpace = Object3DControlContext.World.GetWorldUnitsPerScreenPixelAtPosition(edgePosition); switch (edgeIndex) { case 0: boxCenter.Y += selectCubeSize / 2 * distBetweenPixelsWorldSpace; break; case 1: boxCenter.X -= selectCubeSize / 2 * distBetweenPixelsWorldSpace; break; case 2: boxCenter.Y -= selectCubeSize / 2 * distBetweenPixelsWorldSpace; break; case 3: boxCenter.X += selectCubeSize / 2 * distBetweenPixelsWorldSpace; break; } boxCenter.Z += selectCubeSize / 2 * distBetweenPixelsWorldSpace; var rotation = Matrix4X4.CreateRotation(new Quaternion(selectedItem.Matrix)); var centerMatrix = Matrix4X4.CreateTranslation(boxCenter); centerMatrix = rotation * Matrix4X4.CreateScale(distBetweenPixelsWorldSpace) * centerMatrix; TotalTransform = centerMatrix; }
public override async void OnMouseMove(Mouse3DEventArgs mouseEvent3D, bool mouseIsOver) { var selectedItem = RootSelection; ActiveSelectedItem = selectedItem; if (MouseIsOver || MouseDownOnControl) { xValueDisplayInfo.Visible = true; yValueDisplayInfo.Visible = true; } else if (!hadClickOnControl || scaleController.HasChange) { xValueDisplayInfo.Visible = false; yValueDisplayInfo.Visible = false; } if (MouseDownOnControl && hitPlane != null) { var info = hitPlane.GetClosestIntersection(mouseEvent3D.MouseRay); if (info != null && selectedItem != null) { var lockedEdge = ObjectSpace.GetCornerPosition(selectedItem, quadrantIndex + 2); var delta = info.HitPosition - initialHitPosition; var corner0 = ObjectSpace.GetCornerPosition(selectedItem, quadrantIndex); var corner1 = ObjectSpace.GetCornerPosition(selectedItem, quadrantIndex + 1); var corner3 = ObjectSpace.GetCornerPosition(selectedItem, quadrantIndex + 3); var direction01 = (corner0 - corner1).GetNormal(); var direction03 = (corner0 - corner3).GetNormal(); var deltaAlong01 = direction01.Dot(delta); var deltaAlong03 = direction03.Dot(delta); // scale it var newSize = new Vector2(scaleController.InitialState.Width, scaleController.InitialState.Depth); if (quadrantIndex % 2 == 0) { newSize.X += deltaAlong01; newSize.X = Math.Max(Math.Max(newSize.X, .001), Object3DControlContext.SnapGridDistance); newSize.Y += deltaAlong03; newSize.Y = Math.Max(Math.Max(newSize.Y, .001), Object3DControlContext.SnapGridDistance); } else { newSize.X += deltaAlong03; newSize.X = Math.Max(Math.Max(newSize.X, .001), Object3DControlContext.SnapGridDistance); newSize.Y += deltaAlong01; newSize.Y = Math.Max(Math.Max(newSize.Y, .001), Object3DControlContext.SnapGridDistance); } if (Object3DControlContext.SnapGridDistance > 0) { // snap this position to the grid double snapGridDistance = Object3DControlContext.SnapGridDistance; // snap this position to the grid newSize.X = ((int)((newSize.X / snapGridDistance) + .5)) * snapGridDistance; newSize.Y = ((int)((newSize.Y / snapGridDistance) + .5)) * snapGridDistance; } scaleController.ScaleWidthDepth(newSize.X, newSize.Y); await selectedItem.Rebuild(); // and keep the locked edge in place var newLockedEdge = ObjectSpace.GetCornerPosition(selectedItem, quadrantIndex + 2); selectedItem.Matrix *= Matrix4X4.CreateTranslation(lockedEdge - newLockedEdge); Invalidate(); } } base.OnMouseMove(mouseEvent3D, mouseIsOver); }
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; }