jimmy tremblay-Bernier c1bf5a4ca1 initial commit
2022-03-12 22:04:30 -04:00

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;
}
}
}