private void SelectAxis() { // Get mouse ray Ray ray = Owner.MouseRay; // Transform ray into local space of the gizmo Ray localRay; Matrix invGizmoWorld; Matrix.Invert(ref _gizmoWorld, out invGizmoWorld); Vector3.TransformNormal(ref ray.Direction, ref invGizmoWorld, out localRay.Direction); Vector3.Transform(ref ray.Position, ref invGizmoWorld, out localRay.Position); // Find gizmo collisions with mouse float closestintersection = float.MaxValue; float intersection; _activeAxis = Axis.None; switch (_activeMode) { case Mode.Translate: { // Axis boxes collision if (XAxisBox.Intersects(ref localRay, out intersection) && intersection < closestintersection) { _activeAxis = Axis.X; closestintersection = intersection; } if (YAxisBox.Intersects(ref localRay, out intersection) && intersection < closestintersection) { _activeAxis = Axis.Y; closestintersection = intersection; } if (ZAxisBox.Intersects(ref localRay, out intersection) && intersection < closestintersection) { _activeAxis = Axis.Z; closestintersection = intersection; } // Quad planes collision if (closestintersection >= float.MaxValue) { closestintersection = float.MinValue; } if (XYBox.Intersects(ref localRay, out intersection) && intersection > closestintersection) { _activeAxis = Axis.XY; closestintersection = intersection; } if (XZBox.Intersects(ref localRay, out intersection) && intersection > closestintersection) { _activeAxis = Axis.ZX; closestintersection = intersection; } if (YZBox.Intersects(ref localRay, out intersection) && intersection > closestintersection) { _activeAxis = Axis.YZ; closestintersection = intersection; } break; } case Mode.Rotate: { // Circles if (IntersectsRotateCircle(Vector3.UnitX, ref localRay, out intersection) && intersection < closestintersection) { _activeAxis = Axis.X; closestintersection = intersection; } if (IntersectsRotateCircle(Vector3.UnitY, ref localRay, out intersection) && intersection < closestintersection) { _activeAxis = Axis.Y; closestintersection = intersection; } if (IntersectsRotateCircle(Vector3.UnitZ, ref localRay, out intersection) && intersection < closestintersection) { _activeAxis = Axis.Z; closestintersection = intersection; } // Center /*if (CenterSphere.Intersects(ref ray, out intersection) && intersection < closestintersection) * { * _activeAxis = Axis.Center; * closestintersection = intersection; * }*/ break; } case Mode.Scale: { // Spheres collision if (ScaleXSphere.Intersects(ref ray, out intersection) && intersection < closestintersection) { _activeAxis = Axis.X; closestintersection = intersection; } if (ScaleYSphere.Intersects(ref ray, out intersection) && intersection < closestintersection) { _activeAxis = Axis.Y; closestintersection = intersection; } if (ScaleZSphere.Intersects(ref ray, out intersection) && intersection < closestintersection) { _activeAxis = Axis.Z; closestintersection = intersection; } // Center if (CenterBox.Intersects(ref ray, out intersection) && intersection < closestintersection) { _activeAxis = Axis.Center; closestintersection = intersection; } break; } } }
/// <summary> /// Per-frame check to see if mouse is hovering over any axis. /// </summary> private void SelectAxis(Vector2 mousePosition) { if (!Enabled) { return; } float closestintersection = float.MaxValue; Ray ray = ConvertMouseToRay(mousePosition); if (ActiveMode == GizmoMode.Translate) { // transform ray into local-space of the boundingboxes. ray.Direction = Vector3.TransformNormal(ray.Direction, Matrix.Invert(_gizmoWorld)); ray.Position = Vector3.Transform(ray.Position, Matrix.Invert(_gizmoWorld)); } #region X,Y,Z Boxes float?intersection = XAxisBox.Intersects(ray); if (intersection.HasValue) { if (intersection.Value < closestintersection) { ActiveAxis = GizmoAxis.X; closestintersection = intersection.Value; } } intersection = YAxisBox.Intersects(ray); if (intersection.HasValue) { if (intersection.Value < closestintersection) { ActiveAxis = GizmoAxis.Y; closestintersection = intersection.Value; } } intersection = ZAxisBox.Intersects(ray); if (intersection.HasValue) { if (intersection.Value < closestintersection) { ActiveAxis = GizmoAxis.Z; closestintersection = intersection.Value; } } #endregion if (ActiveMode == GizmoMode.Rotate || ActiveMode == GizmoMode.UniformScale || ActiveMode == GizmoMode.NonUniformScale) { #region BoundingSpheres intersection = XSphere.Intersects(ray); if (intersection.HasValue) { if (intersection.Value < closestintersection) { ActiveAxis = GizmoAxis.X; closestintersection = intersection.Value; } } intersection = YSphere.Intersects(ray); if (intersection.HasValue) { if (intersection.Value < closestintersection) { ActiveAxis = GizmoAxis.Y; closestintersection = intersection.Value; } } intersection = ZSphere.Intersects(ray); if (intersection.HasValue) { if (intersection.Value < closestintersection) { ActiveAxis = GizmoAxis.Z; closestintersection = intersection.Value; } } #endregion } if (ActiveMode == GizmoMode.Translate || ActiveMode == GizmoMode.NonUniformScale || ActiveMode == GizmoMode.UniformScale) { // if no axis was hit (x,y,z) set value to lowest possible to select the 'farthest' intersection for the XY,XZ,YZ boxes. // This is done so you may still select multi-axis if you're looking at the gizmo from behind! if (closestintersection >= float.MaxValue) { closestintersection = float.MinValue; } #region BoundingBoxes intersection = XYBox.Intersects(ray); if (intersection.HasValue) { if (intersection.Value > closestintersection) { ActiveAxis = GizmoAxis.XY; closestintersection = intersection.Value; } } intersection = XZAxisBox.Intersects(ray); if (intersection.HasValue) { if (intersection.Value > closestintersection) { ActiveAxis = GizmoAxis.ZX; closestintersection = intersection.Value; } } intersection = YZBox.Intersects(ray); if (intersection.HasValue) { if (intersection.Value > closestintersection) { ActiveAxis = GizmoAxis.YZ; closestintersection = intersection.Value; } } #endregion } if (closestintersection >= float.MaxValue || closestintersection <= float.MinValue) { ActiveAxis = GizmoAxis.None; } }