227 lines
7.9 KiB
C#
227 lines
7.9 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using UnityEngine;
|
|
|
|
namespace Omni
|
|
{
|
|
public class OmniDataComponent: MonoBehaviour
|
|
{
|
|
protected OmniManager omniManager;
|
|
|
|
protected int startingStepCount;
|
|
|
|
[Header("Output and Calculated Variables. Can be used to debug or poll during game.")]
|
|
[HideInInspector]
|
|
public Vector2 hidInput; // holds x and y values for movement from the controller
|
|
[HideInInspector]
|
|
public float currentOmniYaw;
|
|
[HideInInspector]
|
|
public int currentStepCount;
|
|
[HideInInspector]
|
|
public float omniOffset = 0f;
|
|
[HideInInspector]
|
|
public float angleBetweenOmniAndCamera;
|
|
|
|
[HideInInspector]
|
|
[Range(0.0f, 1.0f)]
|
|
[Tooltip("Fully coupled to camera = 100%, Fully decoupled (follows torso/ring angle = 0%.")]
|
|
public float couplingPercentage = 1.0f;
|
|
protected bool hasSetCouplingPercentage = false;
|
|
|
|
protected byte rawX = 0;
|
|
protected byte rawY = 0;
|
|
protected float omniX = 0;
|
|
protected float omniY = 0;
|
|
|
|
/* Disable unused variable warnings */
|
|
#pragma warning disable 0414
|
|
protected static OmniCommon.Messages.OmniRawData rawData;
|
|
protected static OmniCommon.Messages.OmniMotionData motionData;
|
|
#pragma warning restore 0414
|
|
|
|
private bool debugNotReceivingData = false;
|
|
private bool hasReceivedOmniData = false;
|
|
|
|
public void Setup(OmniManager manager)
|
|
{
|
|
omniManager = manager;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Pulls packets from the Omni and decodes them to populate the class variables and motiondata.
|
|
/// </summary>
|
|
public void ReadAndSetOmniData(OmniConnectionComponent connection, bool hasFullyInitialized)
|
|
{
|
|
ReadOmniData(connection);
|
|
SetAfterReadOmniData(hasFullyInitialized);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Pulls packets from the Omni and decodes them to populate the motiondata.
|
|
/// </summary>
|
|
private void ReadOmniData(OmniConnectionComponent connection)
|
|
{
|
|
byte[] packet = null;
|
|
|
|
if (omniManager.ReadData(ref packet) > 0)
|
|
{
|
|
OmniCommon.Messages.OmniBaseMessage obm = OmniCommon.OmniPacketBuilder.decodePacket(packet);
|
|
|
|
if (debugNotReceivingData == true || hasReceivedOmniData == false)
|
|
{
|
|
Debug.Log(System.DateTime.Now.ToLongTimeString() + ": OmniDataComponent(ReadOmniData) - During this frame, the Omni started reading data from the Omni data packet.");
|
|
debugNotReceivingData = false;
|
|
StartCoroutine(connection.ConfigureOmniConnect());
|
|
|
|
}
|
|
hasReceivedOmniData = true;
|
|
|
|
if (obm != null)
|
|
{
|
|
switch (obm.MsgType)
|
|
{
|
|
case OmniCommon.Messages.MessageType.OmniMotionAndRawDataMessage:
|
|
OmniCommon.Messages.OmniMotionAndRawDataMessage OmniMotionAndRawData = new OmniCommon.Messages.OmniMotionAndRawDataMessage(obm);
|
|
motionData = OmniMotionAndRawData.GetMotionData();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
motionData = null;
|
|
if (debugNotReceivingData == false)
|
|
{
|
|
Debug.LogError(System.DateTime.Now.ToLongTimeString() + ": OmniDataComponent(ReadOmniData) - During this frame, the Omni stopped receiving valid data from the Omni data packet.");
|
|
debugNotReceivingData = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Populate the class variables from motiondata.
|
|
/// </summary>
|
|
private void SetAfterReadOmniData(bool hasFullyInitialized)
|
|
{
|
|
if (!IsMotionDataUnknown())
|
|
{
|
|
currentOmniYaw = motionData.RingAngle;
|
|
|
|
rawX = motionData.GamePad_X;
|
|
rawY = motionData.GamePad_Y;
|
|
omniX = motionData.GamePad_X;
|
|
omniY = motionData.GamePad_Y;
|
|
|
|
if (omniX > 0)
|
|
{
|
|
omniX = (omniX / 255.0f) * 2f - 1f;
|
|
}
|
|
else
|
|
omniX = -1f;
|
|
|
|
if (omniY > 0)
|
|
{
|
|
omniY = (omniY / 255.0f) * 2f - 1f;
|
|
}
|
|
else
|
|
omniY = -1;
|
|
|
|
//clamp '0'
|
|
if (rawX == 127)
|
|
{
|
|
omniX = 0f;
|
|
}
|
|
if (rawY == 127)
|
|
{
|
|
omniY = 0f;
|
|
}
|
|
|
|
omniY *= -1f;
|
|
hidInput = new Vector2(omniX, omniY);
|
|
|
|
if (hasFullyInitialized) UpdateStepCountFromMotionData();
|
|
}
|
|
else
|
|
{
|
|
hidInput = Vector2.zero;
|
|
}
|
|
}
|
|
|
|
public void SetCouplingPercentage(bool needsCoupling)
|
|
{
|
|
if (hasSetCouplingPercentage == false)
|
|
{
|
|
couplingPercentage = !needsCoupling ? 1.0f : OmniMovementCalibration.GetCouplingPercentage();
|
|
hasSetCouplingPercentage = true;
|
|
|
|
Debug.Log(System.DateTime.Now.ToLongTimeString() + ": OmniDataComponent(GetOmniInputForCharacterMovement) - Coupling Percentage = " + couplingPercentage);
|
|
}
|
|
}
|
|
|
|
public float CalculateForwardRotation(bool needsCoupling)
|
|
{
|
|
//keep within bounds (0, 360)
|
|
if (currentOmniYaw > 360f) currentOmniYaw -= 360f;
|
|
if (currentOmniYaw < 0f) currentOmniYaw += 360f;
|
|
|
|
//Get the coupling percentage from Omniverse
|
|
SetCouplingPercentage(needsCoupling);
|
|
|
|
//calculate forward rotation
|
|
return (currentOmniYaw - omniOffset + transform.rotation.eulerAngles.y) + (angleBetweenOmniAndCamera * couplingPercentage);
|
|
}
|
|
|
|
//angle difference between camera and omni angle, used for decoupled effect
|
|
public void ComputeAngleBetweenControllerAndCamera(Transform cameraReference)
|
|
{
|
|
float cameraYaw = cameraReference.rotation.eulerAngles.y;
|
|
float adjustedOmniYaw = currentOmniYaw - omniOffset + transform.rotation.eulerAngles.y;
|
|
|
|
angleBetweenOmniAndCamera = Mathf.Abs(cameraYaw - adjustedOmniYaw) % 360;
|
|
angleBetweenOmniAndCamera = angleBetweenOmniAndCamera > 180 ? 360 - angleBetweenOmniAndCamera : angleBetweenOmniAndCamera;
|
|
|
|
//calculate sign
|
|
float angleForSignCalculation = (cameraYaw - adjustedOmniYaw) % 360;
|
|
|
|
float sign = (angleForSignCalculation >= 0 && angleForSignCalculation <= 180) ||
|
|
(angleForSignCalculation <= -180 && angleForSignCalculation >= -360) ? 1 : -1;
|
|
|
|
angleBetweenOmniAndCamera *= sign;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates step count from motion data after getting the initial step count in the align.
|
|
/// </summary>
|
|
protected void UpdateStepCountFromMotionData()
|
|
{
|
|
if (IsMotionDataUnknown()) return;
|
|
currentStepCount = (int)motionData.StepCount - startingStepCount;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resets step counter to 0. Call at anytime you want to reset the step count.
|
|
/// </summary>
|
|
public void ResetStepCount()
|
|
{
|
|
if (IsMotionDataUnknown()) return;
|
|
startingStepCount = (int)motionData.StepCount;
|
|
currentStepCount = 0;
|
|
}
|
|
|
|
public void ResetHasSetCouplingPercentage()
|
|
{
|
|
hasSetCouplingPercentage = false;
|
|
}
|
|
|
|
public bool IsMotionDataUnknown()
|
|
{
|
|
return motionData == null;
|
|
}
|
|
}
|
|
}
|