Skip to content

Instantly share code, notes, and snippets.

@DashW
Last active July 21, 2023 15:44
Show Gist options
  • Save DashW/5687169a0f82fc58c50e34cbedeb7ba5 to your computer and use it in GitHub Desktop.
Save DashW/5687169a0f82fc58c50e34cbedeb7ba5 to your computer and use it in GitHub Desktop.
Unity Behaviour to counteract 're-centering' on the Oculus Quest and keep the camera centered relative to the Guardian Boundaries
using UnityEngine;
// This behaviour disables 're-centering' on the Oculus Quest,
// instead forcing the camera origin to remain centered and
// facing the same direction within the Guardian boundaries,
// even between app restarts.
public class RecenterResetter : MonoBehaviour
{
public OVRCameraRig CameraRig = null;
public enum FacingEdge
{
Unspecified,
LongEdge,
ShortEdge
}
[Tooltip("Specifies whether the 'Forward' (+Z) direction of the camera origin should be facing a Long or Short edge of the rectangular Guardian Play Area.")]
public FacingEdge Facing = FacingEdge.Unspecified;
public float RotationOffset { get; private set; } = 0.0f;
public Vector3 CenterOffset { get; private set; } = Vector3.zero;
// Start is called before the first frame update
void Start()
{
ResetRecenter();
}
// Update is called once per frame
void Update()
{
if (Mathf.Floor(Time.timeSinceLevelLoad) > Mathf.Floor(Time.timeSinceLevelLoad - Time.deltaTime))
{
ResetRecenter();
}
}
void ResetRecenter()
{
Vector3[] boundaryPoints = OVRManager.boundary.GetGeometry(OVRBoundary.BoundaryType.PlayArea);
CenterOffset = Vector3.zero;
Vector3 v;
for (int i = 0; i < boundaryPoints.Length; ++i)
{
v = boundaryPoints[i];
v.y = 0.0f;
CenterOffset += v;
}
CenterOffset /= boundaryPoints.Length;
if (boundaryPoints.Length > 3)
{
float firstLineLength = (boundaryPoints[1] - boundaryPoints[0]).magnitude;
float secondLineLength = (boundaryPoints[2] - boundaryPoints[1]).magnitude;
Vector3 firstLineNormal = Vector3.Cross((boundaryPoints[1] - boundaryPoints[0]).normalized, Vector3.up).normalized;
float rotationOffset = (Mathf.Atan2(firstLineNormal.x, firstLineNormal.z) * Mathf.Rad2Deg) - 90.0f;
if (Facing == FacingEdge.LongEdge && firstLineLength > secondLineLength
|| Facing == FacingEdge.ShortEdge && secondLineLength > firstLineLength)
{
rotationOffset += 90.0f;
}
Quaternion rotationQuat = Quaternion.Euler(0.0f, rotationOffset, 0.0f);
if (CameraRig != null)
{
CameraRig.trackingSpace.localPosition = Quaternion.Inverse(rotationQuat) * (-CenterOffset);
CameraRig.trackingSpace.localRotation = Quaternion.Inverse(rotationQuat);
}
}
}
}
@DashW
Copy link
Author

DashW commented May 8, 2019

Please note that this functionality has been superseded by 'Stage-Space Tracking' in the latest Oculus Unity Plugin.

In the OVRManager component, set 'Tracking Origin Type' to 'Stage'. This will have the same effect and greater accuracy & reliability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment