206 lines
6.9 KiB
C#
206 lines
6.9 KiB
C#
/*
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
* All rights reserved.
|
|
*
|
|
* Licensed under the Oculus SDK License Agreement (the "License");
|
|
* you may not use the Oculus SDK except in compliance with the License,
|
|
* which is provided at the time of installation or download, or which
|
|
* otherwise accompanies this software in either electronic or hard copy form.
|
|
*
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* https://developer.oculus.com/licenses/oculussdk/
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
|
* 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 System;
|
|
using Meta.XR.Util;
|
|
using UnityEngine;
|
|
using UnityEngine.Assertions;
|
|
using UnityEngine.Serialization;
|
|
using UnityEngine.XR;
|
|
|
|
namespace Oculus.Interaction.Input
|
|
{
|
|
[Feature(Feature.Interaction)]
|
|
public class FromOVRHmdDataSource : DataSource<HmdDataAsset>
|
|
{
|
|
[Header("OVR Data Source")]
|
|
[SerializeField, Interface(typeof(IOVRCameraRigRef))]
|
|
private UnityEngine.Object _cameraRigRef;
|
|
|
|
public IOVRCameraRigRef CameraRigRef { get; private set; }
|
|
|
|
[SerializeField]
|
|
private bool _processLateUpdates = false;
|
|
|
|
[SerializeField]
|
|
[Tooltip("If true, uses OVRManager.headPoseRelativeOffset rather than sensor data for " +
|
|
"HMD pose.")]
|
|
private bool _useOvrManagerEmulatedPose = false;
|
|
|
|
[Header("Shared Configuration")]
|
|
[SerializeField, Interface(typeof(ITrackingToWorldTransformer))]
|
|
private UnityEngine.Object _trackingToWorldTransformer;
|
|
private ITrackingToWorldTransformer TrackingToWorldTransformer;
|
|
|
|
public bool ProcessLateUpdates
|
|
{
|
|
get
|
|
{
|
|
return _processLateUpdates;
|
|
}
|
|
set
|
|
{
|
|
_processLateUpdates = value;
|
|
}
|
|
}
|
|
|
|
private HmdDataAsset _hmdDataAsset = new HmdDataAsset();
|
|
private HmdDataSourceConfig _config;
|
|
|
|
protected void Awake()
|
|
{
|
|
CameraRigRef = _cameraRigRef as IOVRCameraRigRef;
|
|
TrackingToWorldTransformer = _trackingToWorldTransformer as ITrackingToWorldTransformer;
|
|
}
|
|
|
|
protected override void Start()
|
|
{
|
|
this.BeginStart(ref _started, () => base.Start());
|
|
this.AssertField(CameraRigRef, nameof(CameraRigRef));
|
|
this.AssertField(TrackingToWorldTransformer, nameof(TrackingToWorldTransformer));
|
|
this.EndStart(ref _started);
|
|
}
|
|
|
|
protected override void OnEnable()
|
|
{
|
|
base.OnEnable();
|
|
if (_started)
|
|
{
|
|
CameraRigRef.WhenInputDataDirtied += HandleInputDataDirtied;
|
|
}
|
|
}
|
|
|
|
protected override void OnDisable()
|
|
{
|
|
if (_started)
|
|
{
|
|
CameraRigRef.WhenInputDataDirtied -= HandleInputDataDirtied;
|
|
}
|
|
|
|
base.OnDisable();
|
|
|
|
MarkInputDataRequiresUpdate();
|
|
}
|
|
|
|
private void HandleInputDataDirtied(bool isLateUpdate)
|
|
{
|
|
if (isLateUpdate && !_processLateUpdates)
|
|
{
|
|
return;
|
|
}
|
|
MarkInputDataRequiresUpdate();
|
|
}
|
|
|
|
private HmdDataSourceConfig Config
|
|
{
|
|
get
|
|
{
|
|
if (_config != null)
|
|
{
|
|
return _config;
|
|
}
|
|
|
|
_config = new HmdDataSourceConfig()
|
|
{
|
|
TrackingToWorldTransformer = TrackingToWorldTransformer
|
|
};
|
|
|
|
return _config;
|
|
}
|
|
}
|
|
|
|
protected override void UpdateData()
|
|
{
|
|
_hmdDataAsset.Config = Config;
|
|
bool hmdPresent = OVRNodeStateProperties.IsHmdPresent() && this.isActiveAndEnabled;
|
|
ref var centerEyePose = ref _hmdDataAsset.Root;
|
|
if (_useOvrManagerEmulatedPose)
|
|
{
|
|
Quaternion emulatedRotation = Quaternion.Euler(
|
|
-OVRManager.instance.headPoseRelativeOffsetRotation.x,
|
|
-OVRManager.instance.headPoseRelativeOffsetRotation.y,
|
|
OVRManager.instance.headPoseRelativeOffsetRotation.z);
|
|
centerEyePose.rotation = emulatedRotation;
|
|
centerEyePose.position = OVRManager.instance.headPoseRelativeOffsetTranslation;
|
|
hmdPresent = true;
|
|
}
|
|
else
|
|
{
|
|
var previousEyePose = Pose.identity;
|
|
|
|
if (_hmdDataAsset.IsTracked)
|
|
{
|
|
previousEyePose = _hmdDataAsset.Root;
|
|
}
|
|
|
|
if (hmdPresent)
|
|
{
|
|
// These are already in Unity's coordinate system (LHS)
|
|
if (!OVRNodeStateProperties.GetNodeStatePropertyVector3(XRNode.CenterEye,
|
|
NodeStatePropertyType.Position, OVRPlugin.Node.EyeCenter,
|
|
OVRPlugin.Step.Render, out centerEyePose.position))
|
|
{
|
|
centerEyePose.position = previousEyePose.position;
|
|
}
|
|
|
|
if (!OVRNodeStateProperties.GetNodeStatePropertyQuaternion(XRNode.CenterEye,
|
|
NodeStatePropertyType.Orientation, OVRPlugin.Node.EyeCenter,
|
|
OVRPlugin.Step.Render, out centerEyePose.rotation))
|
|
{
|
|
centerEyePose.rotation = previousEyePose.rotation;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
centerEyePose = previousEyePose;
|
|
}
|
|
}
|
|
|
|
_hmdDataAsset.IsTracked = hmdPresent;
|
|
_hmdDataAsset.FrameId = Time.frameCount;
|
|
}
|
|
|
|
protected override HmdDataAsset DataAsset => _hmdDataAsset;
|
|
|
|
#region Inject
|
|
|
|
public void InjectAllFromOVRHmdDataSource(UpdateModeFlags updateMode, IDataSource updateAfter,
|
|
bool useOvrManagerEmulatedPose, ITrackingToWorldTransformer trackingToWorldTransformer)
|
|
{
|
|
base.InjectAllDataSource(updateMode, updateAfter);
|
|
InjectUseOvrManagerEmulatedPose(useOvrManagerEmulatedPose);
|
|
InjectTrackingToWorldTransformer(trackingToWorldTransformer);
|
|
}
|
|
|
|
public void InjectUseOvrManagerEmulatedPose(bool useOvrManagerEmulatedPose)
|
|
{
|
|
_useOvrManagerEmulatedPose = useOvrManagerEmulatedPose;
|
|
}
|
|
|
|
public void InjectTrackingToWorldTransformer(ITrackingToWorldTransformer trackingToWorldTransformer)
|
|
{
|
|
_trackingToWorldTransformer = trackingToWorldTransformer as UnityEngine.Object;
|
|
TrackingToWorldTransformer = trackingToWorldTransformer;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|