Files
UltimateFishing/Assets/Scripts/Assembly-CSharp/OvrAvatar.cs
2026-02-21 16:45:37 +08:00

1114 lines
34 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using BitStrap;
using Oculus.Avatar;
using UnityEngine;
public class OvrAvatar : MonoBehaviour
{
public class PacketEventArgs : EventArgs
{
public readonly OvrAvatarPacket Packet;
public PacketEventArgs(OvrAvatarPacket packet)
{
Packet = packet;
}
}
public enum HandType
{
Right = 0,
Left = 1,
Max = 2
}
public enum HandJoint
{
HandBase = 0,
IndexBase = 1,
IndexTip = 2,
ThumbBase = 3,
ThumbTip = 4,
Max = 5
}
public OvrAvatarMaterialManager DefaultBodyMaterialManager;
public OvrAvatarMaterialManager DefaultHandMaterialManager;
public OvrAvatarDriver Driver;
internal OvrAvatarBase Base;
internal OvrAvatarTouchController ControllerLeft;
internal OvrAvatarTouchController ControllerRight;
internal OvrAvatarBody Body;
internal OvrAvatarHand HandLeft;
internal OvrAvatarHand HandRight;
[ReadOnly]
public Transform leftControllerAnchor;
[ReadOnly]
public Transform rightControllerAnchor;
[Header("Oculus User ID")]
public string oculusUserID;
internal ulong oculusUserIDInternal;
[Header("Capabilities")]
public bool EnableBody = true;
public bool EnableHands = true;
public bool EnableBase = true;
public bool EnableExpressive;
[Header("Network")]
public bool RecordPackets;
public bool UseSDKPackets = true;
public PacketRecordSettings PacketSettings = new PacketRecordSettings();
[Header("Other")]
public bool StartWithControllers;
public AvatarLayer FirstPersonLayer;
public AvatarLayer ThirdPersonLayer;
public bool ShowFirstPerson = true;
public bool ShowThirdPerson;
public bool CanOwnMicrophone = true;
internal ovrAvatarCapabilities Capabilities = ovrAvatarCapabilities.Body;
[Tooltip("Enable this to use transparent queue, disable to use for geometry queue. Requires restart to take effect.")]
[Header("Shaders")]
public bool UseTransparentRenderQueue = true;
public Shader Monochrome_SurfaceShader;
public Shader Monochrome_SurfaceShader_SelfOccluding;
public Shader Monochrome_SurfaceShader_PBS;
public Shader Skinshaded_SurfaceShader_SingleComponent;
public Shader Skinshaded_VertFrag_SingleComponent;
public Shader Skinshaded_VertFrag_CombinedMesh;
public Shader Skinshaded_Expressive_SurfaceShader_SingleComponent;
public Shader Skinshaded_Expressive_VertFrag_SingleComponent;
public Shader Skinshaded_Expressive_VertFrag_CombinedMesh;
public Shader Loader_VertFrag_CombinedMesh;
public Shader EyeLens;
private static readonly Vector3 MOUTH_HEAD_OFFSET;
private const string MOUTH_HELPER_NAME = "MouthAnchor";
private OVRLipSyncMicInput micInput;
private OVRLipSyncContext lipsyncContext;
private OVRLipSync.Frame currentFrame = new OVRLipSync.Frame();
private float[] visemes = new float[15];
private AudioSource audioSource;
private ONSPAudioSource spatializedSource;
private int renderPartCount;
private bool showLeftController;
private bool showRightController;
private List<float[]> voiceUpdates = new List<float[]>();
private bool CombineMeshes;
private bool ForceMobileTextureFormat;
private bool WaitingForCombinedMesh;
public IntPtr sdkAvatar = IntPtr.Zero;
private HashSet<ulong> assetLoadingIds = new HashSet<ulong>();
private Dictionary<string, OvrAvatarComponent> trackedComponents = new Dictionary<string, OvrAvatarComponent>();
private bool assetsFinishedLoading;
private static bool doneExpressiveGlobalInit;
[Header("Misc")]
public GameObject MouthAnchor;
public Transform LeftHandCustomPose;
public Transform RightHandCustomPose;
private Transform cachedLeftHandCustomPose;
private Transform[] cachedCustomLeftHandJoints;
private ovrAvatarTransform[] cachedLeftHandTransforms;
private Transform cachedRightHandCustomPose;
private Transform[] cachedCustomRightHandJoints;
private ovrAvatarTransform[] cachedRightHandTransforms;
private Vector4 clothingAlphaOffset = new Vector4(0f, 0f, 0f, 1f);
private ulong clothingAlphaTexture;
private OvrAvatarPacket CurrentUnityPacket;
private static string[,] HandJoints;
internal ovrAvatarAssetLevelOfDetail LevelOfDetail = ovrAvatarAssetLevelOfDetail.Highest;
internal ovrAvatarLookAndFeelVersion LookAndFeelVersion = ovrAvatarLookAndFeelVersion.Two;
internal ovrAvatarLookAndFeelVersion FallbackLookAndFeelVersion;
private static ovrAvatarVisemes RuntimeVisemes;
public EventHandler<PacketEventArgs> PacketRecorded;
private static Vector3 MOUTH_POSITION_OFFSET;
private static string VOICE_PROPERTY;
private static string MOUTH_POSITION_PROPERTY;
private static string MOUTH_DIRECTION_PROPERTY;
private static string MOUTH_SCALE_PROPERTY;
private static float MOUTH_SCALE_GLOBAL;
private static float MOUTH_MAX_GLOBAL;
private static string NECK_JONT;
public float VoiceAmplitude;
public bool EnableMouthVertexAnimation;
static OvrAvatar()
{
MOUTH_HEAD_OFFSET = new Vector3(0f, -0.085f, 0.09f);
doneExpressiveGlobalInit = false;
HandJoints = new string[2, 5]
{
{ "hands:r_hand_world", "hands:r_hand_world/hands:b_r_hand/hands:b_r_index1", "hands:r_hand_world/hands:b_r_hand/hands:b_r_index1/hands:b_r_index2/hands:b_r_index3/hands:b_r_index_ignore", "hands:r_hand_world/hands:b_r_hand/hands:b_r_thumb1/hands:b_r_thumb2", "hands:r_hand_world/hands:b_r_hand/hands:b_r_thumb1/hands:b_r_thumb2/hands:b_r_thumb3/hands:b_r_thumb_ignore" },
{ "hands:l_hand_world", "hands:l_hand_world/hands:b_l_hand/hands:b_l_index1", "hands:l_hand_world/hands:b_l_hand/hands:b_l_index1/hands:b_l_index2/hands:b_l_index3/hands:b_l_index_ignore", "hands:l_hand_world/hands:b_l_hand/hands:b_l_thumb1/hands:b_l_thumb2", "hands:l_hand_world/hands:b_l_hand/hands:b_l_thumb1/hands:b_l_thumb2/hands:b_l_thumb3/hands:b_l_thumb_ignore" }
};
MOUTH_POSITION_OFFSET = new Vector3(0f, -0.018f, 0.1051f);
VOICE_PROPERTY = "_Voice";
MOUTH_POSITION_PROPERTY = "_MouthPosition";
MOUTH_DIRECTION_PROPERTY = "_MouthDirection";
MOUTH_SCALE_PROPERTY = "_MouthEffectScale";
MOUTH_SCALE_GLOBAL = 0.007f;
MOUTH_MAX_GLOBAL = 0.007f;
NECK_JONT = "root_JNT/body_JNT/chest_JNT/neckBase_JNT/neck_JNT";
RuntimeVisemes.visemeParams = new float[32];
RuntimeVisemes.visemeParamCount = 15u;
}
private void OnEnable()
{
if ((bool)VRControllersManager.Instance && (bool)ControllerRight)
{
VRControllersManager.Instance.ChangeAvatar(this);
}
}
private void OnDestroy()
{
if (sdkAvatar != IntPtr.Zero)
{
CAPI.ovrAvatar_Destroy(sdkAvatar);
}
}
public void AssetLoadedCallback(OvrAvatarAsset asset)
{
assetLoadingIds.Remove(asset.assetID);
}
public void CombinedMeshLoadedCallback(IntPtr assetPtr)
{
if (WaitingForCombinedMesh)
{
ulong[] array = CAPI.ovrAvatarAsset_GetCombinedMeshIDs(assetPtr);
ulong[] array2 = array;
foreach (ulong item in array2)
{
assetLoadingIds.Remove(item);
}
CAPI.ovrAvatar_GetCombinedMeshAlphaData(sdkAvatar, ref clothingAlphaTexture, ref clothingAlphaOffset);
WaitingForCombinedMesh = false;
}
}
private void AddAvatarComponent(GameObject componentObject, ovrAvatarComponent component)
{
OvrAvatarComponent ovrAvatarComponent2 = componentObject.AddComponent<OvrAvatarComponent>();
trackedComponents.Add(component.name, ovrAvatarComponent2);
if (ovrAvatarComponent2.name == "body")
{
ovrAvatarComponent2.ClothingAlphaOffset = clothingAlphaOffset;
ovrAvatarComponent2.ClothingAlphaTexture = clothingAlphaTexture;
}
AddRenderParts(ovrAvatarComponent2, component, componentObject.transform);
}
private OvrAvatarSkinnedMeshRenderComponent AddSkinnedMeshRenderComponent(GameObject gameObject, ovrAvatarRenderPart_SkinnedMeshRender skinnedMeshRender)
{
OvrAvatarSkinnedMeshRenderComponent ovrAvatarSkinnedMeshRenderComponent = gameObject.AddComponent<OvrAvatarSkinnedMeshRenderComponent>();
ovrAvatarSkinnedMeshRenderComponent.Initialize(skinnedMeshRender, Monochrome_SurfaceShader, Monochrome_SurfaceShader_SelfOccluding, ThirdPersonLayer.layerIndex, FirstPersonLayer.layerIndex, renderPartCount++);
return ovrAvatarSkinnedMeshRenderComponent;
}
private OvrAvatarSkinnedMeshRenderPBSComponent AddSkinnedMeshRenderPBSComponent(GameObject gameObject, ovrAvatarRenderPart_SkinnedMeshRenderPBS skinnedMeshRenderPBS)
{
OvrAvatarSkinnedMeshRenderPBSComponent ovrAvatarSkinnedMeshRenderPBSComponent = gameObject.AddComponent<OvrAvatarSkinnedMeshRenderPBSComponent>();
ovrAvatarSkinnedMeshRenderPBSComponent.Initialize(skinnedMeshRenderPBS, Monochrome_SurfaceShader_PBS, ThirdPersonLayer.layerIndex, FirstPersonLayer.layerIndex, renderPartCount++);
return ovrAvatarSkinnedMeshRenderPBSComponent;
}
private OvrAvatarSkinnedMeshPBSV2RenderComponent AddSkinnedMeshRenderPBSV2Component(IntPtr renderPart, GameObject go, ovrAvatarRenderPart_SkinnedMeshRenderPBS_V2 skinnedMeshRenderPBSV2, OvrAvatarMaterialManager materialManager, bool isBodyPartZero, bool isControllerModel)
{
OvrAvatarSkinnedMeshPBSV2RenderComponent ovrAvatarSkinnedMeshPBSV2RenderComponent = go.AddComponent<OvrAvatarSkinnedMeshPBSV2RenderComponent>();
ovrAvatarSkinnedMeshPBSV2RenderComponent.Initialize(renderPart, skinnedMeshRenderPBSV2, materialManager, ThirdPersonLayer.layerIndex, FirstPersonLayer.layerIndex, renderPartCount++, isBodyPartZero && CombineMeshes, LevelOfDetail, isBodyPartZero && EnableExpressive, this, isControllerModel);
return ovrAvatarSkinnedMeshPBSV2RenderComponent;
}
private OvrAvatarProjectorRenderComponent AddProjectorRenderComponent(GameObject gameObject, ovrAvatarRenderPart_ProjectorRender projectorRender)
{
ovrAvatarComponent ovrAvatarComponent2 = CAPI.ovrAvatarComponent_Get(sdkAvatar, projectorRender.componentIndex);
OvrAvatarComponent value;
if (trackedComponents.TryGetValue(ovrAvatarComponent2.name, out value) && projectorRender.renderPartIndex < value.RenderParts.Count)
{
OvrAvatarRenderComponent target = value.RenderParts[(int)projectorRender.renderPartIndex];
OvrAvatarProjectorRenderComponent ovrAvatarProjectorRenderComponent = gameObject.AddComponent<OvrAvatarProjectorRenderComponent>();
ovrAvatarProjectorRenderComponent.InitializeProjectorRender(projectorRender, Monochrome_SurfaceShader, target);
return ovrAvatarProjectorRenderComponent;
}
return null;
}
public static IntPtr GetRenderPart(ovrAvatarComponent component, uint renderPartIndex)
{
long num = Marshal.SizeOf(typeof(IntPtr)) * renderPartIndex;
IntPtr ptr = new IntPtr(component.renderParts.ToInt64() + num);
return (IntPtr)Marshal.PtrToStructure(ptr, typeof(IntPtr));
}
private void UpdateAvatarComponent(ovrAvatarComponent component)
{
OvrAvatarComponent value;
if (!trackedComponents.TryGetValue(component.name, out value))
{
throw new Exception(string.Format("trackedComponents didn't have {0}", component.name));
}
value.UpdateAvatar(component, this);
}
private static string GetRenderPartName(ovrAvatarComponent component, uint renderPartIndex)
{
return component.name + "_renderPart_" + (int)renderPartIndex;
}
internal static void ConvertTransform(ovrAvatarTransform transform, Transform target)
{
Vector3 position = transform.position;
position.z = 0f - position.z;
Quaternion orientation = transform.orientation;
orientation.x = 0f - orientation.x;
orientation.y = 0f - orientation.y;
target.localPosition = position;
target.localRotation = orientation;
target.localScale = transform.scale;
}
public static ovrAvatarTransform CreateOvrAvatarTransform(Vector3 position, Quaternion orientation)
{
return new ovrAvatarTransform
{
position = new Vector3(position.x, position.y, 0f - position.z),
orientation = new Quaternion(0f - orientation.x, 0f - orientation.y, orientation.z, orientation.w),
scale = Vector3.one
};
}
private static ovrAvatarGazeTarget CreateOvrGazeTarget(uint targetId, Vector3 targetPosition, ovrAvatarGazeTargetType targetType)
{
return new ovrAvatarGazeTarget
{
id = targetId,
worldPosition = new Vector3(targetPosition.x, targetPosition.y, 0f - targetPosition.z),
type = targetType
};
}
private void BuildRenderComponents()
{
ovrAvatarHandComponent? ovrAvatarHandComponent2 = CAPI.ovrAvatarPose_GetLeftHandComponent(sdkAvatar);
ovrAvatarHandComponent? ovrAvatarHandComponent3 = CAPI.ovrAvatarPose_GetRightHandComponent(sdkAvatar);
ovrAvatarBodyComponent? ovrAvatarBodyComponent2 = CAPI.ovrAvatarPose_GetBodyComponent(sdkAvatar);
ovrAvatarControllerComponent? ovrAvatarControllerComponent2 = CAPI.ovrAvatarPose_GetLeftControllerComponent(sdkAvatar);
ovrAvatarControllerComponent? ovrAvatarControllerComponent3 = CAPI.ovrAvatarPose_GetRightControllerComponent(sdkAvatar);
ovrAvatarBaseComponent? ovrAvatarBaseComponent2 = CAPI.ovrAvatarPose_GetBaseComponent(sdkAvatar);
uint num = CAPI.ovrAvatarComponent_Count(sdkAvatar);
for (uint num2 = 0u; num2 < num; num2++)
{
IntPtr intPtr = CAPI.ovrAvatarComponent_Get_Native(sdkAvatar, num2);
ovrAvatarComponent component = (ovrAvatarComponent)Marshal.PtrToStructure(intPtr, typeof(ovrAvatarComponent));
if (!trackedComponents.ContainsKey(component.name))
{
GameObject gameObject = new GameObject();
gameObject.name = component.name;
gameObject.transform.SetParent(base.transform);
AddAvatarComponent(gameObject, component);
if (ovrAvatarHandComponent2.HasValue && intPtr == ovrAvatarHandComponent2.Value.renderComponent)
{
HandLeft = gameObject.AddComponent<OvrAvatarHand>();
}
if (ovrAvatarHandComponent3.HasValue && intPtr == ovrAvatarHandComponent3.Value.renderComponent)
{
HandRight = gameObject.AddComponent<OvrAvatarHand>();
}
if (ovrAvatarBodyComponent2.HasValue && intPtr == ovrAvatarBodyComponent2.Value.renderComponent)
{
Body = gameObject.AddComponent<OvrAvatarBody>();
}
if (ovrAvatarControllerComponent2.HasValue && intPtr == ovrAvatarControllerComponent2.Value.renderComponent)
{
ControllerLeft = gameObject.AddComponent<OvrAvatarTouchController>();
}
if (ovrAvatarControllerComponent3.HasValue && intPtr == ovrAvatarControllerComponent3.Value.renderComponent)
{
ControllerRight = gameObject.AddComponent<OvrAvatarTouchController>();
}
if (ovrAvatarBaseComponent2.HasValue && intPtr == ovrAvatarBaseComponent2.Value.renderComponent)
{
Base = gameObject.AddComponent<OvrAvatarBase>();
}
}
}
Utilities.SetLayerRecursively(ControllerLeft.gameObject, "TransparentFX");
Utilities.SetLayerRecursively(ControllerRight.gameObject, "TransparentFX");
Body.gameObject.SetActive(false);
HandLeft.gameObject.SetActive(false);
HandRight.gameObject.SetActive(false);
if ((bool)VRControllersManager.Instance)
{
VRControllersManager.Instance.ChangeAvatar(this);
}
}
private void UpdateSDKAvatarUnityState()
{
uint num = CAPI.ovrAvatarComponent_Count(sdkAvatar);
for (uint num2 = 0u; num2 < num; num2++)
{
IntPtr ptr = CAPI.ovrAvatarComponent_Get_Native(sdkAvatar, num2);
ovrAvatarComponent component = (ovrAvatarComponent)Marshal.PtrToStructure(ptr, typeof(ovrAvatarComponent));
UpdateAvatarComponent(component);
}
UpdateVoiceBehavior();
}
private void UpdateCustomPoses()
{
if (UpdatePoseRoot(LeftHandCustomPose, ref cachedLeftHandCustomPose, ref cachedCustomLeftHandJoints, ref cachedLeftHandTransforms) && cachedLeftHandCustomPose == null && sdkAvatar != IntPtr.Zero)
{
CAPI.ovrAvatar_SetLeftHandGesture(sdkAvatar, ovrAvatarHandGesture.Default);
}
if (UpdatePoseRoot(RightHandCustomPose, ref cachedRightHandCustomPose, ref cachedCustomRightHandJoints, ref cachedRightHandTransforms) && cachedRightHandCustomPose == null && sdkAvatar != IntPtr.Zero)
{
CAPI.ovrAvatar_SetRightHandGesture(sdkAvatar, ovrAvatarHandGesture.Default);
}
if (sdkAvatar != IntPtr.Zero)
{
if (cachedLeftHandCustomPose != null && UpdateTransforms(cachedCustomLeftHandJoints, cachedLeftHandTransforms))
{
CAPI.ovrAvatar_SetLeftHandCustomGesture(sdkAvatar, (uint)cachedLeftHandTransforms.Length, cachedLeftHandTransforms);
}
if (cachedRightHandCustomPose != null && UpdateTransforms(cachedCustomRightHandJoints, cachedRightHandTransforms))
{
CAPI.ovrAvatar_SetRightHandCustomGesture(sdkAvatar, (uint)cachedRightHandTransforms.Length, cachedRightHandTransforms);
}
}
}
private static bool UpdatePoseRoot(Transform poseRoot, ref Transform cachedPoseRoot, ref Transform[] cachedPoseJoints, ref ovrAvatarTransform[] transforms)
{
if (poseRoot == cachedPoseRoot)
{
return false;
}
if (!poseRoot)
{
cachedPoseRoot = null;
cachedPoseJoints = null;
transforms = null;
}
else
{
List<Transform> list = new List<Transform>();
OrderJoints(poseRoot, list);
cachedPoseRoot = poseRoot;
cachedPoseJoints = list.ToArray();
transforms = new ovrAvatarTransform[list.Count];
}
return true;
}
private static bool UpdateTransforms(Transform[] joints, ovrAvatarTransform[] transforms)
{
bool result = false;
for (int i = 0; i < joints.Length; i++)
{
Transform transform = joints[i];
ovrAvatarTransform ovrAvatarTransform2 = CreateOvrAvatarTransform(transform.localPosition, transform.localRotation);
if (ovrAvatarTransform2.position != transforms[i].position || ovrAvatarTransform2.orientation != transforms[i].orientation)
{
transforms[i] = ovrAvatarTransform2;
result = true;
}
}
return result;
}
private static void OrderJoints(Transform transform, List<Transform> joints)
{
joints.Add(transform);
for (int i = 0; i < transform.childCount; i++)
{
Transform child = transform.GetChild(i);
OrderJoints(child, joints);
}
}
private void AvatarSpecificationCallback(IntPtr avatarSpecification)
{
sdkAvatar = CAPI.ovrAvatar_Create(avatarSpecification, Capabilities);
ShowLeftController(showLeftController);
ShowRightController(showRightController);
uint num = CAPI.ovrAvatar_GetReferencedAssetCount(sdkAvatar);
for (uint num2 = 0u; num2 < num; num2++)
{
ulong num3 = CAPI.ovrAvatar_GetReferencedAsset(sdkAvatar, num2);
if (OvrAvatarSDKManager.Instance.GetAsset(num3) == null)
{
OvrAvatarSDKManager.Instance.BeginLoadingAsset(num3, LevelOfDetail, AssetLoadedCallback);
assetLoadingIds.Add(num3);
}
}
if (CombineMeshes)
{
OvrAvatarSDKManager.Instance.RegisterCombinedMeshCallback(sdkAvatar, CombinedMeshLoadedCallback);
}
}
private void Start()
{
if (CombineMeshes)
{
CombineMeshes = false;
}
try
{
oculusUserIDInternal = ulong.Parse(oculusUserID);
}
catch (Exception)
{
oculusUserIDInternal = 0uL;
}
Capabilities = (ovrAvatarCapabilities)0;
if (EnableBody)
{
Capabilities |= ovrAvatarCapabilities.Body;
}
if (EnableHands)
{
Capabilities |= ovrAvatarCapabilities.Hands;
}
if (EnableBase && EnableBody)
{
Capabilities |= ovrAvatarCapabilities.Base;
}
if (EnableExpressive)
{
Capabilities |= ovrAvatarCapabilities.Expressive;
}
Capabilities |= ovrAvatarCapabilities.BodyTilt;
leftControllerAnchor = base.transform.parent.Find("LeftHandAnchor").Find("LeftControllerAnchor");
rightControllerAnchor = base.transform.parent.Find("RightHandAnchor").Find("RightControllerAnchor");
ShowLeftController(StartWithControllers);
ShowRightController(StartWithControllers);
OvrAvatarSDKManager.Instance.RequestAvatarSpecification(oculusUserIDInternal, AvatarSpecificationCallback, CombineMeshes, LevelOfDetail, ForceMobileTextureFormat, LookAndFeelVersion, FallbackLookAndFeelVersion, EnableExpressive);
WaitingForCombinedMesh = CombineMeshes;
if (Driver != null)
{
Driver.Mode = ((!UseSDKPackets) ? OvrAvatarDriver.PacketMode.Unity : OvrAvatarDriver.PacketMode.SDK);
}
}
private void Update()
{
if (sdkAvatar == IntPtr.Zero)
{
return;
}
if (Driver != null)
{
Driver.UpdateTransforms(sdkAvatar);
foreach (float[] voiceUpdate in voiceUpdates)
{
CAPI.ovrAvatarPose_UpdateVoiceVisualization(sdkAvatar, voiceUpdate);
}
voiceUpdates.Clear();
CAPI.ovrAvatarPose_Finalize(sdkAvatar, Time.deltaTime);
}
if (RecordPackets)
{
RecordFrame();
}
if (assetLoadingIds.Count == 0)
{
if (!assetsFinishedLoading)
{
BuildRenderComponents();
InitPostLoad();
assetsFinishedLoading = true;
}
UpdateSDKAvatarUnityState();
UpdateCustomPoses();
if (EnableExpressive)
{
UpdateExpressive();
}
}
}
public static ovrAvatarHandInputState CreateInputState(ovrAvatarTransform transform, OvrAvatarDriver.ControllerPose pose)
{
return new ovrAvatarHandInputState
{
transform = transform,
buttonMask = pose.buttons,
touchMask = pose.touches,
joystickX = pose.joystickPosition.x,
joystickY = pose.joystickPosition.y,
indexTrigger = pose.indexTrigger,
handTrigger = pose.handTrigger,
isActive = pose.isActive
};
}
public void ShowControllers(bool show)
{
ShowLeftController(show);
ShowRightController(show);
}
public void ShowLeftController(bool show)
{
if (sdkAvatar != IntPtr.Zero)
{
CAPI.ovrAvatar_SetLeftControllerVisibility(sdkAvatar, show);
}
showLeftController = show;
}
public void ShowRightController(bool show)
{
if (sdkAvatar != IntPtr.Zero)
{
CAPI.ovrAvatar_SetRightControllerVisibility(sdkAvatar, show);
}
showRightController = show;
}
public void UpdateVoiceVisualization(float[] voiceSamples)
{
voiceUpdates.Add(voiceSamples);
}
private void RecordFrame()
{
if (UseSDKPackets)
{
RecordSDKFrame();
}
else
{
RecordUnityFrame();
}
}
private void RecordUnityFrame()
{
float num = Time.deltaTime;
OvrAvatarDriver.PoseFrame currentPose = Driver.GetCurrentPose();
if (CurrentUnityPacket == null)
{
CurrentUnityPacket = new OvrAvatarPacket(currentPose);
num = 0f;
}
float num2 = 0f;
while (num2 < num)
{
float num3 = num - num2;
float num4 = PacketSettings.UpdateRate - CurrentUnityPacket.Duration;
if (num3 < num4)
{
CurrentUnityPacket.AddFrame(currentPose, num3);
num2 += num3;
continue;
}
OvrAvatarDriver.PoseFrame finalFrame = CurrentUnityPacket.FinalFrame;
OvrAvatarDriver.PoseFrame b = currentPose;
float t = num4 / num3;
OvrAvatarDriver.PoseFrame poseFrame = OvrAvatarDriver.PoseFrame.Interpolate(finalFrame, b, t);
CurrentUnityPacket.AddFrame(poseFrame, num4);
num2 += num4;
if (PacketRecorded != null)
{
PacketRecorded(this, new PacketEventArgs(CurrentUnityPacket));
}
CurrentUnityPacket = new OvrAvatarPacket(poseFrame);
}
}
private void RecordSDKFrame()
{
if (sdkAvatar == IntPtr.Zero)
{
return;
}
if (!PacketSettings.RecordingFrames)
{
CAPI.ovrAvatarPacket_BeginRecording(sdkAvatar);
PacketSettings.AccumulatedTime = 0f;
PacketSettings.RecordingFrames = true;
}
PacketSettings.AccumulatedTime += Time.deltaTime;
if (PacketSettings.AccumulatedTime >= PacketSettings.UpdateRate)
{
PacketSettings.AccumulatedTime = 0f;
IntPtr intPtr = CAPI.ovrAvatarPacket_EndRecording(sdkAvatar);
CAPI.ovrAvatarPacket_BeginRecording(sdkAvatar);
if (PacketRecorded != null)
{
PacketRecorded(this, new PacketEventArgs(new OvrAvatarPacket
{
ovrNativePacket = intPtr
}));
}
CAPI.ovrAvatarPacket_Free(intPtr);
}
}
private void AddRenderParts(OvrAvatarComponent ovrComponent, ovrAvatarComponent component, Transform parent)
{
bool flag = ovrComponent.name == "body";
bool flag2 = ovrComponent.name == "controller_left";
bool flag3 = ovrComponent.name == "controller_right";
for (uint num = 0u; num < component.renderPartCount; num++)
{
GameObject gameObject = new GameObject();
gameObject.name = GetRenderPartName(component, num);
gameObject.transform.SetParent(parent);
IntPtr renderPart = GetRenderPart(component, num);
ovrAvatarRenderPartType ovrAvatarRenderPartType2 = CAPI.ovrAvatarRenderPart_GetType(renderPart);
OvrAvatarRenderComponent item;
switch (ovrAvatarRenderPartType2)
{
case ovrAvatarRenderPartType.SkinnedMeshRender:
item = AddSkinnedMeshRenderComponent(gameObject, CAPI.ovrAvatarRenderPart_GetSkinnedMeshRender(renderPart));
break;
case ovrAvatarRenderPartType.SkinnedMeshRenderPBS:
item = AddSkinnedMeshRenderPBSComponent(gameObject, CAPI.ovrAvatarRenderPart_GetSkinnedMeshRenderPBS(renderPart));
break;
case ovrAvatarRenderPartType.ProjectorRender:
item = AddProjectorRenderComponent(gameObject, CAPI.ovrAvatarRenderPart_GetProjectorRender(renderPart));
break;
case ovrAvatarRenderPartType.SkinnedMeshRenderPBS_V2:
item = AddSkinnedMeshRenderPBSV2Component(renderPart, gameObject, CAPI.ovrAvatarRenderPart_GetSkinnedMeshRenderPBSV2(renderPart), (!flag) ? DefaultHandMaterialManager : DefaultBodyMaterialManager, flag && num == 0, flag2 || flag3);
break;
default:
throw new NotImplementedException(string.Format("Unsupported render part type: {0}", ovrAvatarRenderPartType2.ToString()));
}
ovrComponent.RenderParts.Add(item);
}
}
public void RefreshBodyParts()
{
if (!(Body != null))
{
return;
}
OvrAvatarComponent component = Body.GetComponent<OvrAvatarComponent>();
foreach (OvrAvatarRenderComponent renderPart in component.RenderParts)
{
UnityEngine.Object.Destroy(renderPart.gameObject);
}
component.RenderParts.Clear();
ovrAvatarBodyComponent? ovrAvatarBodyComponent2 = CAPI.ovrAvatarPose_GetBodyComponent(sdkAvatar);
if (ovrAvatarBodyComponent2.HasValue)
{
ovrAvatarComponent component2 = (ovrAvatarComponent)Marshal.PtrToStructure(ovrAvatarBodyComponent2.Value.renderComponent, typeof(ovrAvatarComponent));
AddRenderParts(component, component2, Body.gameObject.transform);
return;
}
throw new Exception("Destroyed the body component, but didn't find a new one in the SDK");
}
public ovrAvatarBodyComponent? GetBodyComponent()
{
return CAPI.ovrAvatarPose_GetBodyComponent(sdkAvatar);
}
public Transform GetHandTransform(HandType hand, HandJoint joint)
{
if (hand >= HandType.Max || joint >= HandJoint.Max)
{
return null;
}
OvrAvatarHand ovrAvatarHand = ((hand != HandType.Left) ? HandRight : HandLeft);
if (ovrAvatarHand != null)
{
OvrAvatarComponent component = ovrAvatarHand.GetComponent<OvrAvatarComponent>();
if (component != null && component.RenderParts.Count > 0)
{
OvrAvatarRenderComponent ovrAvatarRenderComponent = component.RenderParts[0];
return ovrAvatarRenderComponent.transform.Find(HandJoints[(int)hand, (int)joint]);
}
}
return null;
}
public void GetPointingDirection(HandType hand, ref Vector3 forward, ref Vector3 up)
{
Transform handTransform = GetHandTransform(hand, HandJoint.HandBase);
if (handTransform != null)
{
forward = handTransform.forward;
up = handTransform.up;
}
}
public Transform GetMouthTransform()
{
OvrAvatarComponent value;
if (trackedComponents.TryGetValue("voice", out value) && value.RenderParts.Count > 0)
{
return value.RenderParts[0].transform;
}
return null;
}
private void UpdateVoiceBehavior()
{
if (EnableMouthVertexAnimation && Body != null)
{
OvrAvatarComponent component = Body.GetComponent<OvrAvatarComponent>();
VoiceAmplitude = Mathf.Clamp(VoiceAmplitude, 0f, 1f);
if (component.RenderParts.Count > 0)
{
Material sharedMaterial = component.RenderParts[0].mesh.sharedMaterial;
Transform transform = component.RenderParts[0].mesh.transform.Find(NECK_JONT);
Vector3 vector = transform.TransformPoint(Vector3.up) - transform.position;
sharedMaterial.SetFloat(MOUTH_SCALE_PROPERTY, vector.magnitude);
sharedMaterial.SetFloat(VOICE_PROPERTY, Mathf.Min(vector.magnitude * MOUTH_MAX_GLOBAL, vector.magnitude * VoiceAmplitude * MOUTH_SCALE_GLOBAL));
sharedMaterial.SetVector(MOUTH_POSITION_PROPERTY, transform.TransformPoint(MOUTH_POSITION_OFFSET));
sharedMaterial.SetVector(MOUTH_DIRECTION_PROPERTY, transform.up);
}
}
}
private bool IsValidMic()
{
if (Microphone.devices.Length < 1)
{
return false;
}
string deviceName = Microphone.devices[0].ToString();
int minFreq;
int maxFreq;
Microphone.GetDeviceCaps(deviceName, out minFreq, out maxFreq);
if (maxFreq == 0)
{
maxFreq = 44100;
}
AudioClip audioClip = Microphone.Start(deviceName, true, 1, maxFreq);
if (audioClip == null)
{
return false;
}
Microphone.End(deviceName);
return true;
}
private void InitPostLoad()
{
ExpressiveGlobalInit();
ConfigureHelpers();
if (GetComponent<OvrAvatarLocalDriver>() != null)
{
lipsyncContext.audioLoopback = false;
if (CanOwnMicrophone && IsValidMic())
{
micInput = MouthAnchor.gameObject.AddComponent<OVRLipSyncMicInput>();
micInput.enableMicSelectionGUI = false;
micInput.MicFrequency = 44100f;
micInput.micControl = OVRLipSyncMicInput.micActivation.ConstantSpeak;
}
}
}
private static void ExpressiveGlobalInit()
{
if (doneExpressiveGlobalInit)
{
return;
}
doneExpressiveGlobalInit = true;
ovrAvatarLights lights = new ovrAvatarLights
{
ambientIntensity = RenderSettings.ambientLight.grayscale * 0.5f,
lights = new ovrAvatarLight[16]
};
Light[] array = UnityEngine.Object.FindObjectsOfType(typeof(Light)) as Light[];
int num = 0;
foreach (Light light in array)
{
if ((bool)light && light.enabled)
{
uint instanceID = (uint)light.transform.GetInstanceID();
switch (light.type)
{
case LightType.Directional:
lights.lights[num++] = CreateLightDirectional(instanceID, light.transform.forward, light.intensity);
break;
case LightType.Point:
lights.lights[num++] = CreateLightPoint(instanceID, light.transform.position, light.range, light.intensity);
break;
case LightType.Spot:
lights.lights[num++] = CreateLightSpot(instanceID, light.transform.position, light.transform.forward, light.spotAngle, light.range, light.intensity);
break;
}
}
if (num >= 16)
{
break;
}
}
lights.lightCount = (uint)num;
CAPI.ovrAvatar_UpdateLights(lights);
}
private static ovrAvatarLight CreateLightDirectional(uint id, Vector3 direction, float intensity)
{
return new ovrAvatarLight
{
id = id,
type = ovrAvatarLightType.Direction,
worldDirection = new Vector3(direction.x, direction.y, 0f - direction.z),
intensity = intensity
};
}
private static ovrAvatarLight CreateLightPoint(uint id, Vector3 position, float range, float intensity)
{
return new ovrAvatarLight
{
id = id,
type = ovrAvatarLightType.Point,
worldPosition = new Vector3(position.x, position.y, 0f - position.z),
range = range,
intensity = intensity
};
}
private static ovrAvatarLight CreateLightSpot(uint id, Vector3 position, Vector3 direction, float spotAngleDeg, float range, float intensity)
{
return new ovrAvatarLight
{
id = id,
type = ovrAvatarLightType.Spot,
worldPosition = new Vector3(position.x, position.y, 0f - position.z),
worldDirection = new Vector3(direction.x, direction.y, 0f - direction.z),
spotAngleDeg = spotAngleDeg,
range = range,
intensity = intensity
};
}
private void UpdateExpressive()
{
ovrAvatarTransform ovrAvatarTransform2 = CreateOvrAvatarTransform(base.transform.position, base.transform.rotation);
CAPI.ovrAvatar_UpdateWorldTransform(sdkAvatar, ovrAvatarTransform2);
UpdateFacewave();
}
private void ConfigureHelpers()
{
Transform transform = base.transform.Find("body/body_renderPart_0/root_JNT/body_JNT/chest_JNT/neckBase_JNT/neck_JNT/head_JNT");
if (transform == null)
{
transform = base.transform;
}
if (MouthAnchor == null)
{
MouthAnchor = CreateHelperObject(transform, MOUTH_HEAD_OFFSET, "MouthAnchor", string.Empty);
}
if (GetComponent<OvrAvatarLocalDriver>() != null)
{
if (audioSource == null)
{
audioSource = MouthAnchor.gameObject.AddComponent<AudioSource>();
}
spatializedSource = MouthAnchor.GetComponent<ONSPAudioSource>();
if (spatializedSource == null)
{
spatializedSource = MouthAnchor.gameObject.AddComponent<ONSPAudioSource>();
}
spatializedSource.UseInvSqr = true;
spatializedSource.EnableRfl = false;
spatializedSource.EnableSpatialization = true;
spatializedSource.Far = 100f;
spatializedSource.Near = 0.1f;
lipsyncContext = MouthAnchor.GetComponent<OVRLipSyncContext>();
if (lipsyncContext == null)
{
lipsyncContext = MouthAnchor.gameObject.AddComponent<OVRLipSyncContext>();
lipsyncContext.provider = OVRLipSync.ContextProviders.Enhanced;
lipsyncContext.skipAudioSource = !CanOwnMicrophone;
}
StartCoroutine(WaitForMouthAudioSource());
}
if (GetComponent<OvrAvatarRemoteDriver>() != null)
{
GazeTarget gazeTarget = transform.gameObject.AddComponent<GazeTarget>();
gazeTarget.Type = ovrAvatarGazeTargetType.AvatarHead;
Transform transform2 = base.transform.Find("hand_left");
if (!(transform2 == null))
{
GazeTarget gazeTarget2 = transform2.gameObject.AddComponent<GazeTarget>();
gazeTarget2.Type = ovrAvatarGazeTargetType.AvatarHand;
}
transform2 = base.transform.Find("hand_right");
if (!(transform2 == null))
{
GazeTarget gazeTarget3 = transform2.gameObject.AddComponent<GazeTarget>();
gazeTarget3.Type = ovrAvatarGazeTargetType.AvatarHand;
}
}
}
private IEnumerator WaitForMouthAudioSource()
{
while (MouthAnchor.GetComponent<AudioSource>() == null)
{
yield return new WaitForSeconds(0.1f);
}
AudioSource AS = MouthAnchor.GetComponent<AudioSource>();
AS.minDistance = 0.3f;
AS.maxDistance = 4f;
AS.rolloffMode = AudioRolloffMode.Logarithmic;
AS.loop = true;
AS.playOnAwake = true;
AS.spatialBlend = 1f;
AS.spatialize = true;
AS.spatializePostEffects = true;
}
public void DestroyHelperObjects()
{
if ((bool)MouthAnchor)
{
UnityEngine.Object.DestroyImmediate(MouthAnchor.gameObject);
}
}
public GameObject CreateHelperObject(Transform parent, Vector3 localPositionOffset, string helperName, string helperTag = "")
{
GameObject gameObject = new GameObject();
gameObject.name = helperName;
if (helperTag != string.Empty)
{
gameObject.tag = helperTag;
}
gameObject.transform.SetParent(parent);
gameObject.transform.localRotation = Quaternion.identity;
gameObject.transform.localPosition = localPositionOffset;
return gameObject;
}
public void UpdateVoiceData(short[] pcmData, int numChannels)
{
if (lipsyncContext != null && micInput == null)
{
lipsyncContext.ProcessAudioSamplesRaw(pcmData, numChannels);
}
}
public void UpdateVoiceData(float[] pcmData, int numChannels)
{
if (lipsyncContext != null && micInput == null)
{
lipsyncContext.ProcessAudioSamplesRaw(pcmData, numChannels);
}
}
private void UpdateFacewave()
{
if (!(lipsyncContext != null) || (!(micInput != null) && CanOwnMicrophone))
{
return;
}
currentFrame = lipsyncContext.GetCurrentPhonemeFrame();
if (currentFrame.Visemes.Length != 15)
{
Debug.LogError("Unexpected number of visemes " + currentFrame.Visemes);
return;
}
currentFrame.Visemes.CopyTo(visemes, 0);
for (int i = 0; i < 15; i++)
{
RuntimeVisemes.visemeParams[i] = visemes[i];
}
CAPI.ovrAvatar_SetVisemes(sdkAvatar, RuntimeVisemes);
}
}