192 lines
7.0 KiB
C#
192 lines
7.0 KiB
C#
// Copyright 2016 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.
|
|
|
|
// This class is only used in the Editor, so make sure to only compile it on that platform.
|
|
// Additionally, it depends on EmulatorManager which is only compiled in the editor.
|
|
#if UNITY_EDITOR
|
|
|
|
using UnityEngine;
|
|
|
|
/// @cond
|
|
namespace Gvr.Internal {
|
|
/// Controller provider that connects to the controller emulator to obtain controller events.
|
|
class EmulatorControllerProvider : IControllerProvider {
|
|
private ControllerState state = new ControllerState();
|
|
|
|
/// Yaw correction due to recentering.
|
|
private Quaternion yawCorrection = Quaternion.identity;
|
|
|
|
/// True if we performed the initial recenter.
|
|
private bool initialRecenterDone = false;
|
|
|
|
/// The last (uncorrected) orientation received from the emulator.
|
|
private Quaternion lastRawOrientation = Quaternion.identity;
|
|
private GvrControllerButton lastButtonsState;
|
|
|
|
public bool SupportsBatteryStatus {
|
|
get { return true; }
|
|
}
|
|
public int MaxControllerCount {
|
|
get { return 1; }
|
|
}
|
|
|
|
/// Creates a new EmulatorControllerProvider with the specified settings.
|
|
internal EmulatorControllerProvider(GvrControllerInput.EmulatorConnectionMode connectionMode) {
|
|
if (connectionMode == GvrControllerInput.EmulatorConnectionMode.USB) {
|
|
EmulatorConfig.Instance.PHONE_EVENT_MODE = EmulatorConfig.Mode.USB;
|
|
} else if (connectionMode == GvrControllerInput.EmulatorConnectionMode.WIFI) {
|
|
EmulatorConfig.Instance.PHONE_EVENT_MODE = EmulatorConfig.Mode.WIFI;
|
|
} else {
|
|
EmulatorConfig.Instance.PHONE_EVENT_MODE = EmulatorConfig.Mode.OFF;
|
|
}
|
|
|
|
EmulatorManager.Instance.touchEventListeners += HandleTouchEvent;
|
|
EmulatorManager.Instance.orientationEventListeners += HandleOrientationEvent;
|
|
EmulatorManager.Instance.buttonEventListeners += HandleButtonEvent;
|
|
EmulatorManager.Instance.gyroEventListeners += HandleGyroEvent;
|
|
EmulatorManager.Instance.accelEventListeners += HandleAccelEvent;
|
|
}
|
|
|
|
public void Dispose() {}
|
|
|
|
public void ReadState(ControllerState outState, int controller_id) {
|
|
if (controller_id != 0) {
|
|
return;
|
|
}
|
|
lock (state) {
|
|
state.connectionState = GvrConnectionState.Connected;
|
|
if (!EmulatorManager.Instance.Connected) {
|
|
state.connectionState = EmulatorManager.Instance.Connecting ?
|
|
GvrConnectionState.Connecting : GvrConnectionState.Disconnected;
|
|
}
|
|
state.apiStatus = EmulatorManager.Instance.Connected ? GvrControllerApiStatus.Ok :
|
|
GvrControllerApiStatus.Unavailable;
|
|
|
|
// During emulation, just assume the controller is fully charged
|
|
state.isCharging = false;
|
|
state.batteryLevel = GvrControllerBatteryLevel.Full;
|
|
|
|
state.SetButtonsUpDownFromPrevious(lastButtonsState);
|
|
lastButtonsState = state.buttonsState;
|
|
|
|
outState.CopyFrom(state);
|
|
}
|
|
state.ClearTransientState();
|
|
}
|
|
|
|
public void OnPause() {}
|
|
public void OnResume() {}
|
|
|
|
private void HandleTouchEvent(EmulatorTouchEvent touchEvent) {
|
|
if (touchEvent.pointers.Count < 1) return;
|
|
EmulatorTouchEvent.Pointer pointer = touchEvent.pointers[0];
|
|
|
|
lock (state) {
|
|
state.touchPos = new Vector2(pointer.normalizedX, pointer.normalizedY);
|
|
switch (touchEvent.getActionMasked()) {
|
|
case EmulatorTouchEvent.Action.kActionDown:
|
|
state.buttonsState |= GvrControllerButton.TouchPadTouch;
|
|
break;
|
|
case EmulatorTouchEvent.Action.kActionMove:
|
|
state.buttonsState |= GvrControllerButton.TouchPadTouch;
|
|
break;
|
|
case EmulatorTouchEvent.Action.kActionUp:
|
|
state.buttonsState &= ~GvrControllerButton.TouchPadTouch;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void HandleOrientationEvent(EmulatorOrientationEvent orientationEvent) {
|
|
lastRawOrientation = ConvertEmulatorQuaternion(orientationEvent.orientation);
|
|
if (!initialRecenterDone) {
|
|
Recenter();
|
|
initialRecenterDone = true;
|
|
}
|
|
lock (state) {
|
|
state.orientation = yawCorrection * lastRawOrientation;
|
|
}
|
|
}
|
|
|
|
private void HandleButtonEvent(EmulatorButtonEvent buttonEvent) {
|
|
GvrControllerButton buttonMask = 0;
|
|
switch (buttonEvent.code) {
|
|
case EmulatorButtonEvent.ButtonCode.kApp:
|
|
buttonMask = GvrControllerButton.App;
|
|
break;
|
|
case EmulatorButtonEvent.ButtonCode.kHome:
|
|
buttonMask = GvrControllerButton.System;
|
|
break;
|
|
case EmulatorButtonEvent.ButtonCode.kClick:
|
|
buttonMask = GvrControllerButton.TouchPadButton;
|
|
break;
|
|
}
|
|
if (buttonMask != 0) {
|
|
lock (state) {
|
|
state.buttonsState &= ~buttonMask;
|
|
if (buttonEvent.down) {
|
|
state.buttonsState |= buttonMask;
|
|
}
|
|
}
|
|
if (buttonMask == GvrControllerButton.System) {
|
|
if (!buttonEvent.down) {
|
|
// Finished the recentering gesture. Recenter controller.
|
|
Recenter();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void HandleGyroEvent(EmulatorGyroEvent gyroEvent) {
|
|
lock (state) {
|
|
state.gyro = ConvertEmulatorGyro(gyroEvent.value);
|
|
}
|
|
}
|
|
|
|
private void HandleAccelEvent(EmulatorAccelEvent accelEvent) {
|
|
lock (state) {
|
|
state.accel = ConvertEmulatorAccel(accelEvent.value);
|
|
}
|
|
}
|
|
|
|
private static Quaternion ConvertEmulatorQuaternion(Quaternion emulatorQuat) {
|
|
// Convert from the emulator's coordinate space to Unity's standard coordinate space.
|
|
return new Quaternion(emulatorQuat.x, -emulatorQuat.z, emulatorQuat.y, emulatorQuat.w);
|
|
}
|
|
|
|
private static Vector3 ConvertEmulatorGyro(Vector3 emulatorGyro) {
|
|
// Convert from the emulator's coordinate space to Unity's standard coordinate space.
|
|
return new Vector3(-emulatorGyro.x, -emulatorGyro.z, -emulatorGyro.y);
|
|
}
|
|
|
|
private static Vector3 ConvertEmulatorAccel(Vector3 emulatorAccel) {
|
|
// Convert from the emulator's coordinate space to Unity's standard coordinate space.
|
|
return new Vector3(emulatorAccel.x, emulatorAccel.z, emulatorAccel.y);
|
|
}
|
|
|
|
private void Recenter() {
|
|
lock (state) {
|
|
// We want the current orientation to be "forward" so, we set the yaw correction
|
|
// to undo the current rotation's yaw.
|
|
yawCorrection = Quaternion.AngleAxis(-lastRawOrientation.eulerAngles.y, Vector3.up);
|
|
state.orientation = Quaternion.identity;
|
|
state.recentered = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/// @endcond
|
|
|
|
#endif // UNITY_EDITOR
|