Пример #1
0
        /// <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;
        }
Пример #2
0
        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);
        }
Пример #3
0
        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;
            }
        }
Пример #4
0
        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);
        }