/// <summary> /// When the mouse is pressed in the 3D view, we want to select the clicked object. /// </summary> /// <param name="viewport">The viewport that was clicked</param> /// <param name="e">The click event</param> protected override void MouseDown3D(Viewport3D viewport, ViewportEvent e) { // Do not perform selection if space is down if (KeyboardState.IsKeyDown(Keys.Space)) return; // First, get the ray that is cast from the clicked point along the viewport frustrum var ray = viewport.CastRayFromScreen(e.X, e.Y); // Grab all the elements that intersect with the ray var hits = Document.Map.WorldSpawn.GetAllNodesIntersectingWith(ray); // Sort the list of intersecting elements by distance from ray origin IntersectingObjectsFor3DSelection = hits .Select(x => new { Item = x, Intersection = x.GetIntersectionPoint(ray) }) .Where(x => x.Intersection != null) .OrderBy(x => (x.Intersection - ray.Start).VectorMagnitude()) .Select(x => x.Item) .ToList(); // By default, select the closest object ChosenItemFor3DSelection = IntersectingObjectsFor3DSelection.FirstOrDefault(); // If Ctrl is down and the object is already selected, we should deselect it instead. var list = new[] {ChosenItemFor3DSelection}; var desel = ChosenItemFor3DSelection != null && KeyboardState.Ctrl && ChosenItemFor3DSelection.IsSelected; SetSelected(desel ? list : null, desel ? null : list, !KeyboardState.Ctrl, IgnoreGrouping()); State.ActiveViewport = null; }
private void MouseDown(Viewport3D vp, ViewportEvent e) { if (!_currentTool.NoSelection()) { var vtxs = _currentTool.GetVerticesAtPoint(e.X, vp.Height - e.Y, vp); if (vtxs.Any()) { // Use the topmost vertex as the control point var vtx = vtxs.First(); // Mouse down on a point if (vtx.IsSelected && KeyboardState.Ctrl && _currentTool.ShouldDeselect(vtxs)) { // If the vertex is selected and ctrl is down, deselect the vertices vtxs.ForEach(x => x.IsSelected = false); } else { if (!vtx.IsSelected && !KeyboardState.Ctrl && _currentTool.ShouldDeselect(vtxs)) { // If we aren't clicking on a selected point and ctrl is not down, deselect the others Points.ForEach(x => x.IsSelected = false); // If this point is already selected, don't deselect others. This is the same behaviour as 2D selection. } vtxs.ForEach(x => x.IsSelected = true); } VertexSelectionChanged(); // Don't do other click operations return; } // Nothing clicked if (!KeyboardState.Ctrl) { // Deselect all the points if not ctrl-ing Points.ForEach(x => x.IsSelected = false); } } if (!_currentTool.No3DSelection()) { // Do selection var ray = vp.CastRayFromScreen(e.X, e.Y); var hits = Document.Map.WorldSpawn.GetAllNodesIntersectingWith(ray, true); var solid = hits .OfType<Solid>() .Select(x => new { Item = x, Intersection = x.GetIntersectionPoint(ray) }) .Where(x => x.Intersection != null) .OrderBy(x => (x.Intersection - ray.Start).VectorMagnitude()) .Select(x => x.Item) .FirstOrDefault(); if (solid != null) { if (solid.IsSelected && KeyboardState.Ctrl) { // deselect solid var select = new MapObject[0]; var deselect = new[] {solid}; Document.PerformAction("Deselect VM solid", new ChangeSelection(select, deselect)); } else if (!solid.IsSelected) { // select solid var select = new[] {solid}; var deselect = !KeyboardState.Ctrl ? Document.Selection.GetSelectedObjects() : new MapObject[0]; Document.PerformAction("Select VM solid", new ChangeSelection(select, deselect)); } // Don't do other click operations return; } } base.MouseDown(vp, e); }
private void UpdateCurrentFace(Viewport3D viewport, ViewportEvent e) { var ray = viewport.CastRayFromScreen(e.X, e.Y); // The face doesn't change when drawing, just update the intersection if (_state == SketchState.DrawingBase || _state == SketchState.DrawingVolume) { _intersection = (_state == SketchState.DrawingBase ? _currentFace.Plane : _volumePlane).GetIntersectionPoint(ray, true, true); return; } var isect = Document.Map.WorldSpawn.GetAllNodesIntersectingWith(ray) .OfType<Solid>() .SelectMany(x => x.Faces) .Select(x => new { Item = x, Intersection = x.GetIntersectionPoint(ray) }) .Where(x => x.Intersection != null) .OrderBy(x => (x.Intersection - ray.Start).VectorMagnitude()) .FirstOrDefault(); if (isect != null) { if (_currentFace != isect.Item) { _cloneFace = isect.Item.Clone(); _cloneFace.Transform(new UnitTranslate(isect.Item.Plane.Normal * 0.1m), TransformFlags.None); } _currentFace = isect.Item; _intersection = isect.Intersection; _state = SketchState.Ready; } else { _cloneFace = null; _currentFace = null; _intersection = null; _state = SketchState.None; } }
private void MouseDown(Viewport3D vp, ViewportEvent e) { if (vp == null || e.Button != MouseButtons.Left) return; // Get the ray that is cast from the clicked point along the viewport frustrum var ray = vp.CastRayFromScreen(e.X, e.Y); // Grab all the elements that intersect with the ray var hits = Document.Map.WorldSpawn.GetAllNodesIntersectingWith(ray); // Sort the list of intersecting elements by distance from ray origin and grab the first hit var hit = hits .Select(x => new { Item = x, Intersection = x.GetIntersectionPoint(ray) }) .Where(x => x.Intersection != null) .OrderBy(x => (x.Intersection - ray.Start).VectorMagnitude()) .FirstOrDefault(); if (hit == null) return; // Nothing was clicked CreateEntity(hit.Intersection); }