FittsLaw/Assets/GoogleVR/Scripts/Controller/Internal/ControllerProviders/MouseControllerProvider.cs
2018-10-08 23:54:11 -04:00

199 lines
5.7 KiB
C#

// Copyright 2017 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using Gvr;
using UnityEngine;
namespace Gvr.Internal {
/// Mocks controller input by using the mouse.
/// The controller is connected when holding left shift.
/// Move the mouse to control gyroscope and orientation.
/// The left mouse button is used for the clickButton.
/// The right mouse button is used for the appButton.
/// The middle mouse button is used for the homeButton.
class MouseControllerProvider : IControllerProvider {
private const string AXIS_MOUSE_X = "Mouse X";
private const string AXIS_MOUSE_Y = "Mouse Y";
private ControllerState state = new ControllerState();
private Vector2 mouseDelta = new Vector2();
/// Need to store the state of the buttons from the previous frame.
/// This is because Input.GetMouseButtonDown and Input.GetMouseButtonUp
/// don't work when called after WaitForEndOfFrame, which is when ReadState is called.
private bool wasTouching;
private GvrControllerButton lastButtonsState;
private const float ROTATE_SENSITIVITY = 4.5f;
private const float TOUCH_SENSITIVITY = .12f;
private static readonly Vector3 INVERT_Y = new Vector3(1, -1, 1);
public static bool IsMouseAvailable {
get {
return Input.mousePresent && IsActivateButtonPressed;
}
}
public static bool IsActivateButtonPressed {
get {
return Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
}
}
public static bool IsClickButtonPressed {
get {
return Input.GetMouseButton(0);
}
}
public static bool IsAppButtonPressed {
get {
return Input.GetMouseButton(1);
}
}
public static bool IsHomeButtonPressed {
get {
return Input.GetMouseButton(2);
}
}
public static bool IsTouching {
get {
return Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl);
}
}
public bool SupportsBatteryStatus {
get { return false; }
}
public int MaxControllerCount {
get { return 1; }
}
internal MouseControllerProvider() {}
public void Dispose() {}
public void ReadState(ControllerState outState, int controller_id) {
if (controller_id != 0) {
return;
}
lock (state) {
UpdateState();
outState.CopyFrom(state);
}
state.ClearTransientState();
}
public void OnPause() {}
public void OnResume() {}
private void UpdateState() {
GvrCursorHelper.ControllerEmulationActive = IsMouseAvailable;
if (!IsMouseAvailable) {
ClearState();
return;
}
state.connectionState = GvrConnectionState.Connected;
state.apiStatus = GvrControllerApiStatus.Ok;
state.isCharging = false;
state.batteryLevel = GvrControllerBatteryLevel.Full;
UpdateButtonStates();
mouseDelta.Set(
Input.GetAxis(AXIS_MOUSE_X),
Input.GetAxis(AXIS_MOUSE_Y)
);
if (0 != (state.buttonsState & GvrControllerButton.TouchPadTouch)) {
UpdateTouchPos();
} else {
UpdateOrientation();
}
}
private void UpdateTouchPos() {
Vector3 currentMousePosition = Input.mousePosition;
Vector2 touchDelta = mouseDelta * TOUCH_SENSITIVITY;
touchDelta.y *= -1.0f;
state.touchPos += touchDelta;
state.touchPos.x = Mathf.Clamp01(state.touchPos.x);
state.touchPos.y = Mathf.Clamp01(state.touchPos.y);
}
private void UpdateOrientation() {
Vector3 deltaDegrees = Vector3.Scale(mouseDelta, INVERT_Y) * ROTATE_SENSITIVITY;
state.gyro = deltaDegrees * (Mathf.Deg2Rad / Time.deltaTime);
Quaternion yaw = Quaternion.AngleAxis(deltaDegrees.x, Vector3.up);
Quaternion pitch = Quaternion.AngleAxis(deltaDegrees.y, Vector3.right);
state.orientation = state.orientation * yaw * pitch;
}
private void UpdateButtonStates() {
state.buttonsState = 0;
if (IsClickButtonPressed) {
state.buttonsState |= GvrControllerButton.TouchPadButton;
}
if (IsAppButtonPressed) {
state.buttonsState |= GvrControllerButton.App;
}
if (IsHomeButtonPressed) {
state.buttonsState |= GvrControllerButton.System;
}
if (IsTouching) {
state.buttonsState |= GvrControllerButton.TouchPadTouch;
}
state.SetButtonsUpDownFromPrevious(lastButtonsState);
lastButtonsState = state.buttonsState;
if (0 != (state.buttonsUp & GvrControllerButton.TouchPadTouch)) {
ClearTouchPos();
}
if (0 != (state.buttonsUp & GvrControllerButton.System)) {
Recenter();
}
}
private void Recenter() {
Quaternion yawCorrection = Quaternion.AngleAxis(-state.orientation.eulerAngles.y, Vector3.up);
state.orientation = state.orientation * yawCorrection;
state.recentered = true;
}
private void ClearTouchPos() {
state.touchPos = new Vector2(0.5f, 0.5f);
}
private void ClearState() {
state.connectionState = GvrConnectionState.Disconnected;
state.buttonsState = 0;
state.buttonsDown = 0;
state.buttonsUp = 0;
ClearTouchPos();
}
}
}