// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using Microsoft.MixedReality.Toolkit.Physics; using Microsoft.MixedReality.Toolkit.Utilities; using Unity.Profiling; using UnityEngine; using UInput = UnityEngine.Input; namespace Microsoft.MixedReality.Toolkit.Input.UnityInput { [MixedRealityDataProvider( typeof(IMixedRealityInputSystem), (SupportedPlatforms)(-1), // All platforms supported by Unity "Unity Mouse Device Manager", "Profiles/DefaultMixedRealityMouseInputProfile.asset", "MixedRealityToolkit.SDK", requiresProfile: true)] public class MouseDeviceManager : BaseInputDeviceManager, IMixedRealityMouseDeviceManager { /// /// Constructor. /// /// The instance that loaded the data provider. /// The instance that receives data from this provider. /// Friendly name of the service. /// Service priority. Used to determine order of instantiation. /// The service's configuration profile. [System.Obsolete("This constructor is obsolete (registrar parameter is no longer required) and will be removed in a future version of the Microsoft Mixed Reality Toolkit.")] public MouseDeviceManager( IMixedRealityServiceRegistrar registrar, IMixedRealityInputSystem inputSystem, string name = null, uint priority = DefaultPriority, BaseMixedRealityProfile profile = null) : this(inputSystem, name, priority, profile) { Registrar = registrar; } /// /// Constructor. /// /// The instance that receives data from this provider. /// Friendly name of the service. /// Service priority. Used to determine order of instantiation. /// The service's configuration profile. public MouseDeviceManager( IMixedRealityInputSystem inputSystem, string name = null, uint priority = DefaultPriority, BaseMixedRealityProfile profile = null) : base(inputSystem, name, priority, profile) { } // Values defining the range of the cursor and wheel speed multipliers private const float MinSpeedMultiplier = 0.1f; private const float MaxSpeedMultiplier = 10.0f; /// public MixedRealityMouseInputProfile MouseInputProfile => ConfigurationProfile as MixedRealityMouseInputProfile; private float cursorSpeed = 1.0f; /// public float CursorSpeed { get => cursorSpeed; set { if (value != cursorSpeed) { cursorSpeed = Mathf.Clamp(value, MinSpeedMultiplier, MaxSpeedMultiplier); } } } private float wheelSpeed = 1.0f; /// public float WheelSpeed { get => wheelSpeed; set { if (value != wheelSpeed) { wheelSpeed = Mathf.Clamp(value, MinSpeedMultiplier, MaxSpeedMultiplier); } } } /// /// Current Mouse Controller. /// public MouseController Controller { get; private set; } /// public override void Initialize() { base.Initialize(); ReadProfile(); } /// public override void Enable() { base.Enable(); if (!UInput.mousePresent) { Disable(); return; } if (Controller != null) { // device manager has already been set up return; } IMixedRealityInputSource mouseInputSource = null; MixedRealityRaycaster.DebugEnabled = true; const Handedness handedness = Handedness.Any; System.Type controllerType = typeof(MouseController); // Make sure that the handedness declared in the controller attribute matches what we expect var controllerAttribute = MixedRealityControllerAttribute.Find(controllerType); if (controllerAttribute != null) { Handedness[] handednesses = controllerAttribute.SupportedHandedness; Debug.Assert( handednesses.Length == 1 && handednesses[0] == Handedness.Any, "Unexpected mouse handedness declared in MixedRealityControllerAttribute"); } if (Service != null) { var pointers = RequestPointers(SupportedControllerType.Mouse, handedness); mouseInputSource = Service.RequestNewGenericInputSource("Mouse Input", pointers); } Controller = new MouseController(TrackingState.NotApplicable, handedness, mouseInputSource); if (mouseInputSource != null) { for (int i = 0; i < mouseInputSource.Pointers.Length; i++) { mouseInputSource.Pointers[i].Controller = Controller; } } Service?.RaiseSourceDetected(Controller.InputSource, Controller); } private static readonly ProfilerMarker UpdatePerfMarker = new ProfilerMarker("[MRTK] MouseDeviceManager.Update"); /// public override void Update() { using (UpdatePerfMarker.Auto()) { base.Update(); if (UInput.mousePresent && Controller == null) { Enable(); } Controller?.Update(); } } /// public override void Disable() { base.Disable(); if (Controller != null) { Service?.RaiseSourceLost(Controller.InputSource, Controller); RecyclePointers(Controller.InputSource); Controller = null; } } private void ReadProfile() { MixedRealityMouseInputProfile profile = ConfigurationProfile as MixedRealityMouseInputProfile; CursorSpeed = profile.CursorSpeed; WheelSpeed = profile.WheelSpeed; } } }