/// <summary> /// Catching the arrow keys is important here. If we didn't return true then OnKeyDown and OnKeyUp will not get /// called for the arrow keys.</summary> /// <param name="keyData"></param> /// <returns></returns> protected override bool IsInputKey(Keys keyData) { if (InputScheme.ActiveControlScheme.IsInputKey(KeysInterop.ToAtf(keyData))) { return(true); } return(base.IsInputKey(keyData)); }
/// <summary> /// Calling the base ProcessCmdKey allows this keypress to be consumed by owning /// Controls like PropertyView and PropertyGridView and be seen by ControlHostService. /// Returning false allows the keypress to escape to IsInputKey, OnKeyDown, OnKeyUp, etc. /// Returning true means that this keypress has been consumed by this method and this /// event is not passed on to any other methods or Controls.</summary> /// <param name="msg"></param> /// <param name="keyDataWf"></param> /// <returns></returns> protected override bool ProcessCmdKey(ref Message msg, Keys keyDataWf) { if (CameraController.HandlesWASD && InputScheme.ActiveControlScheme.IsInputKey(KeysInterop.ToAtf(keyDataWf))) { return(false); } return(base.ProcessCmdKey(ref msg, keyDataWf)); }
public override bool MouseMove(object sender, MouseEventArgs e) { if (m_dragging && InputScheme.ActiveControlScheme.IsControllingCamera(KeysInterop.ToAtf(Control.ModifierKeys), MouseEventArgsInterop.ToAtf(e))) { Control c = sender as Control; float dx = e.X - m_lastMousePointX; float dy = e.Y - m_lastMousePointY; if (InputScheme.ActiveControlScheme.IsRotating(KeysInterop.ToAtf(Control.ModifierKeys), MouseEventArgsInterop.ToAtf(e)) && (Camera.ViewType == ViewTypes.Perspective || LockOrthographic == false)) { var orbitRotationSpeed = .0005f * (float)Math.PI; // just do this orbitting calculation in spherical coords... // it's much easier than any other method var orbitCenter = Camera.LookAtPoint; var spherical = CartesianToSphericalYUp(orbitCenter - Camera.Eye); spherical[0] += dy * orbitRotationSpeed; spherical[0] = Clamp(spherical[0], (float)Math.PI * 0.02f, (float)Math.PI * 0.98f); spherical[1] += dx * orbitRotationSpeed; var defaultUp = new Vec3F(0.0f, 1.0f, 0.0f); // (geometry gets hopelessly unnormalized if we don't reset default-up here) Camera.Set(orbitCenter - SphericalToCartesianYUp(spherical), orbitCenter, defaultUp); if (Camera.ViewType != ViewTypes.Perspective) { Camera.ViewType = ViewTypes.Perspective; } } else if (InputScheme.ActiveControlScheme.IsZooming(KeysInterop.ToAtf(Control.ModifierKeys), MouseEventArgsInterop.ToAtf(e))) { float zoom = (-dy - dx); float adj = Camera.DistanceFromLookAt; var zoomSpeed = 0.01f * adj; var lookAtDir = Vec3F.Normalize(Camera.LookAt); var movement = Math.Min(zoom * zoomSpeed, Camera.DistanceFromLookAt - 0.1f); Camera.Set(Camera.Eye + lookAtDir * movement, Camera.LookAtPoint, Camera.Up); } else if (InputScheme.ActiveControlScheme.IsPanning(KeysInterop.ToAtf(Control.ModifierKeys), MouseEventArgsInterop.ToAtf(e))) { float adj = Camera.DistanceFromLookAt; var panSpeed = 0.001f * adj; var lookAtPoint = Camera.LookAtPoint; var translation = (Camera.Up * dy * panSpeed) + (Camera.Right * -dx * panSpeed); Camera.Set(Camera.Eye + translation, lookAtPoint + translation, Camera.Up); } m_lastMousePointX = e.Location.X; m_lastMousePointY = e.Location.Y; return(true); } return(base.MouseMove(sender, e)); }
/// <summary> /// Handles mouse-down events</summary> /// <param name="sender">Control that raised original event</param> /// <param name="e">Event args</param> /// <returns>true, if controller handled the event</returns> public override bool MouseDown(object sender, MouseEventArgs e) { if (InputScheme.ActiveControlScheme.IsControllingCamera(KeysInterop.ToAtf(Control.ModifierKeys), MouseEventArgsInterop.ToAtf(e))) { m_lastMousePoint = e.Location; m_dragging = true; return(true); } return(base.MouseDown(sender, e)); }
public override bool MouseDown(object sender, MouseEventArgs e) { if (InputScheme.ActiveControlScheme.IsControllingCamera(KeysInterop.ToAtf(Control.ModifierKeys), MouseEventArgsInterop.ToAtf(e))) { m_lastMousePointX = e.Location.X; m_lastMousePointY = e.Location.Y; m_dragging = true; return(true); } if (Control.ModifierKeys.HasFlag(Keys.Control) && !Control.ModifierKeys.HasFlag(Keys.Shift) && e.Button == MouseButtons.Left) { // "control + l click" repositions the "focus" point of the camera // -- it's just incredibly useful to be able to manually set the point, because it // allows the user to specify both the speed of the movement of the camera and // the orbit of the camera in a natural way // // We could expand "ActiveControlScheme" to allow this key binding to be rebound... // but just using fixed binding for now. // This is a very important key combination (it's just really useful to be able to move // the focus around quickly) -- so it should be accessable with any easy combination from // anywhere! ViewControl c = sender as ViewControl; GUILayer.IViewContext vc = sender as GUILayer.IViewContext; if (c != null && vc != null) { // We can use XLEBridgeUtils to do the ray test. This will // execute the native code (which in turn performs the intersection // on the GPU) // Note that we're using the more complex picking interface because // we want to use explicitly pass "Camera" (rather than // getting it from the view control) var hit = XLEBridgeUtils.Picking.RayPick( GUILayer.EngineDevice.GetInstance(), vc.SceneManager, vc.TechniqueContext, c.GetWorldRay(e.Location), XLEBridgeUtils.Utils.AsCameraDesc(Camera), c.ClientSize, XLEBridgeUtils.Picking.Flags.AllWorldObjects); if (hit != null && hit.Length > 0) { Vec3F transformedPt; Camera.AxisSystem.Transform(hit[0].hitPt, out transformedPt); Camera.Set(Camera.Eye, transformedPt, Camera.Up); } } return(true); } return(base.MouseDown(sender, e)); }
public override bool MouseWheel(object sender, MouseEventArgs e) { if (!InputScheme.ActiveControlScheme.IsZooming(KeysInterop.ToAtf(Control.ModifierKeys), MouseEventArgsInterop.ToAtf(e))) { return(true); } float adj = Camera.DistanceFromLookAt; var zoomSpeed = .1f / 120.0f * adj; var lookAtDir = Vec3F.Normalize(Camera.LookAt); var movement = Math.Min(e.Delta * zoomSpeed, Camera.DistanceFromLookAt - 0.1f); Camera.Set(Camera.Eye + lookAtDir * movement, Camera.LookAtPoint, Camera.Up); return(true); }
/// <summary> /// Calling the base ProcessCmdKey allows this key press to be consumed by owning /// controls like PropertyView and PropertyGridView and be seen by ControlHostService. /// Returning false allows the key press to escape to IsInputKey, OnKeyDown, OnKeyUp, etc. /// Returning true means that this key press has been consumed by this method and this /// event is not passed on to any other methods or controls.</summary> /// <param name="msg">Windows message to process</param> /// <param name="keyDataWf">Key data</param> /// <returns>False to allow the key press to escape to IsInputKey, OnKeyDown, OnKeyUp, etc. /// True to consume this key press, so this /// event is not passed on to any other methods or controls.</returns> protected override bool ProcessCmdKey(ref Message msg, Keys keyDataWf) { var keyData = KeysInterop.ToAtf(keyDataWf); if (m_cameraController.HandlesWASD && (keyData == s_controlScheme.Left1 || keyData == s_controlScheme.Left2 || keyData == s_controlScheme.Right1 || keyData == s_controlScheme.Right2 || keyData == s_controlScheme.Forward1 || keyData == s_controlScheme.Forward2 || keyData == s_controlScheme.Back1 || keyData == s_controlScheme.Back2)) { return(false); } return(base.ProcessCmdKey(ref msg, KeysInterop.ToWf(keyData))); }
/// <summary> /// Handles mouse wheel events for zooming in and out. By the standard of Microsoft /// and AutoCAD and others, scrolling the mouse wheel away from the user zooms in /// and scrolling the mouse wheel towards the user zooms out. </summary> /// <param name="sender">Control that raised original event</param> /// <param name="e">Event args</param> /// <returns>true, if controller handled the event</returns> public override bool MouseWheel(object sender, MouseEventArgs e) { if (!InputScheme.ActiveControlScheme.IsZooming(KeysInterop.ToAtf(Control.ModifierKeys), MouseEventArgsInterop.ToAtf(e))) { return(true); } // disable accelerated vertical scrolling. int eDelta = e.Delta > 0 ? 120 : -120; // on a Logitech mouse, scrolling back by one "notch" made e.Delta be -120. float delta = -eDelta *CalculateZoomScale() * 0.002f; // account for the fact that zooming in starts with a larger look-at distance if (eDelta > 0) { float origLookAtDist = m_distanceFromLookAt; m_distanceFromLookAt += delta; delta = -eDelta *CalculateZoomScale() * 0.002f; m_distanceFromLookAt = origLookAtDist; } //minimum distance to travel in world space with one wheel "notch". If this is too // small, zooming can feel too slow as we get close to the look-at-point. const float min_wheel_delta = 1.5f; if (delta > -min_wheel_delta && delta < min_wheel_delta) { if (delta < 0.0f) { delta = -min_wheel_delta; } else { delta = min_wheel_delta; } } m_distanceFromLookAt += delta; ControllerToCamera(); return(true); }
public static SelectMode GetSelectMode(Keys modifiers) { Sce.Atf.Input.Keys modkeys = KeysInterop.ToAtf(modifiers); if (ActiveControlScheme.ToggleSelection != Sce.Atf.Input.Keys.None && modkeys == ActiveControlScheme.ToggleSelection) { return(SelectMode.Toggle); } if (ActiveControlScheme.AddSelection != Sce.Atf.Input.Keys.None && modkeys == ActiveControlScheme.AddSelection) { return(SelectMode.Extend); } if (ActiveControlScheme.RemoveSelection != Sce.Atf.Input.Keys.None && modkeys == ActiveControlScheme.RemoveSelection) { return(SelectMode.Remove); } return(SelectMode.Normal); }
/// <summary> /// Should the camera turn around in-place? This means that the look-at direction /// changes, but the eye point remains stationary.</summary> /// <param name="controlScheme">The control scheme instance to extend</param> /// <param name="modifierKeys">The camera control's ModifierKeys property</param> /// <param name="e">The camera control's event handler's AtfMouseEventArgs</param> /// <returns>True if the user wants to turn the camera around in place</returns> /// <remarks>This is used by the fly and walk camera controllers.</remarks> public static bool IsTurning(this ControlScheme controlScheme, WfKeys modifierKeys, AtfMouseEventArgs e) { return(controlScheme.IsTurning(KeysInterop.ToAtf(modifierKeys), e)); }
/// <summary> /// Is key an input key for camera motion?</summary> /// <param name="controlScheme">The control scheme instance to extend</param> /// <param name="key">Key to test</param> /// <returns>True iff key is input key for camera motion</returns> public static bool IsInputKey(this ControlScheme controlScheme, WfKeys key) { return(controlScheme.IsInputKey(KeysInterop.ToAtf(key))); }
/// <summary> /// Is the keyboard being used to move the camera? If the camera controller allows /// for this kind of control, then it can check in the OnKeyDown event handler if /// the user is intending to move the camera.</summary> /// <param name="controlScheme">The control scheme instance to extend</param> /// <param name="modifierKeys">The Control's ModifierKeys property</param> /// <param name="e">The key event from the KeyDown event handler, for example</param> /// <returns>True if the user is trying to move the camera using the keyboard</returns> public static bool IsControllingCamera(this ControlScheme controlScheme, WfKeys modifierKeys, WfKeyEventArgs e) { return(controlScheme.IsControllingCamera(KeysInterop.ToAtf(modifierKeys), KeyEventArgsInterop.ToAtf(e))); }
/// <summary> /// Handles mouse-move events</summary> /// <param name="sender">Control that raised original event</param> /// <param name="e">Event args</param> /// <returns>true, if controller handled the event</returns> public override bool MouseMove(object sender, MouseEventArgs e) { if (m_dragging && InputScheme.ActiveControlScheme.IsControllingCamera(KeysInterop.ToAtf(Control.ModifierKeys), MouseEventArgsInterop.ToAtf(e))) { Control c = sender as Control; float dx = (e.X - m_lastMousePoint.X) * (4.0f / c.Width); float dy = (e.Y - m_lastMousePoint.Y) * (4.0f / c.Height); if (InputScheme.ActiveControlScheme.IsRotating(KeysInterop.ToAtf(Control.ModifierKeys), MouseEventArgsInterop.ToAtf(e)) && (Camera.ViewType == ViewTypes.Perspective || LockOrthographic == false)) { // elevation m_elevation += dy; if (m_elevation > PI) { m_elevation -= TwoPI; } else if (m_elevation < -PI) { m_elevation += TwoPI; } // azimuth m_azimuth -= dx; if (m_azimuth > PI) { m_azimuth -= TwoPI; } else if (m_azimuth < -PI) { m_azimuth += TwoPI; } if (Camera.ViewType != ViewTypes.Perspective) { Camera.ViewType = ViewTypes.Perspective; } ControllerToCamera(); } else if (InputScheme.ActiveControlScheme.IsZooming(KeysInterop.ToAtf(Control.ModifierKeys), MouseEventArgsInterop.ToAtf(e))) { float zoom = (-dy - dx); const float ZoomScale = 0.7f; // fudge factor to get the right amount of zoom m_distanceFromLookAt += zoom * CalculateZoomScale() * ZoomScale; ControllerToCamera(); } else if (InputScheme.ActiveControlScheme.IsPanning(KeysInterop.ToAtf(Control.ModifierKeys), MouseEventArgsInterop.ToAtf(e))) { // The fudge factor was calculated so that an object that is fitted to view will have // its pivot point stay under the cursor during panning. This was tested using the proxy // cube. 0.25f was a bit too high. float s = CalculateZoomScale() * 0.21f; if (s > 0) { m_lookAtPoint += Camera.Up * dy * s; m_lookAtPoint += Camera.Right * -dx * s * Camera.Aspect; } else { m_lookAtPoint -= Camera.Up * dy * s; m_lookAtPoint -= Camera.Right * -dx * s * Camera.Aspect; } ControllerToCamera(); } m_lastMousePoint = e.Location; return(true); } return(base.MouseMove(sender, e)); }
/// <summary> /// Processes the key as a command shortcut</summary> /// <param name="commandService">Command service</param> /// <param name="key">Key to process</param> /// <returns>True iff the key was processed as a command shortcut</returns> static public bool ProcessKey(this ICommandService commandService, System.Windows.Forms.Keys key) { return(commandService.ProcessKey(KeysInterop.ToAtf(key))); }
/// <summary> /// Registers a command for the command client</summary> /// <param name="commandService">Command service</param> /// <param name="commandTag">Command's unique ID</param> /// <param name="menuTag">Containing menu's unique ID, or null</param> /// <param name="groupTag">Containing menu group's unique ID, or null</param> /// <param name="menuText">Command text as it appears in menu</param> /// <param name="description">Command description</param> /// <param name="shortcut">Command shortcut, or Keys.None if none</param> /// <param name="imageName">Text identifying image, or null if none</param> /// <param name="visibility">Value describing whether command is visible in menus and toolbars</param> /// <param name="client">Client that performs command</param> /// <returns>CommandInfo object describing command</returns> public static CommandInfo RegisterCommand( this ICommandService commandService, object commandTag, object menuTag, object groupTag, string menuText, string description, System.Windows.Forms.Keys shortcut, string imageName, CommandVisibility visibility, ICommandClient client) { CommandInfo info = new CommandInfo(commandTag, menuTag, groupTag, menuText, description, KeysInterop.ToAtf(shortcut), imageName, visibility); commandService.RegisterCommand(info, client); return(info); }