- Home /
SteamVR: tweak update poses (fake tracking latency)
Hi,
Unity version: 2017.1.0f3
I'm willing to simulate latency in the head tracking of my Oculus: when one moves the head, the image should but updated a few ms later and not "immediately".
Since SteamVR_UpdatePoses is deprecated, the script that handles head position is SteamVR_Render.cs. Here are the lines that seems to be related to the tracking:
// [...]
public TrackedDevicePose_t[] poses = new TrackedDevicePose_t[OpenVR.k_unMaxTrackedDeviceCount];
public TrackedDevicePose_t[] gamePoses = new TrackedDevicePose_t[0];
// [...]
public void UpdatePoses()
{
var compositor = OpenVR.Compositor;
if (compositor != null)
{
compositor.GetLastPoses(poses, gamePoses);
SteamVR_Events.NewPoses.Send(poses);
SteamVR_Events.NewPosesApplied.Send();
}
}
void OnBeforeRender()
{
UpdatePoses();
}
Here is what I tried:
// [...]
public TrackedDevicePose_t[] poses = new TrackedDevicePose_t[OpenVR.k_unMaxTrackedDeviceCount];
public TrackedDevicePose_t[] gamePoses = new TrackedDevicePose_t[0];
// [...]
public void UpdatePoses()
{
var compositor = OpenVR.Compositor;
if (compositor != null)
{
compositor.GetLastPoses(poses, gamePoses);
SteamVR_Events.NewPoses.Send(poses);
SteamVR_Events.NewPosesApplied.Send();
}
}
void OnBeforeRender()
{
StartCoroutine(Lag());
}
private IEnumerator Lag()
{
yield return new WaitForSeconds(1f);
UpdatePoses();
}
As you can see, i only store the current position/rotation values and wait for a given time (1 second here but much less in actual development) before updating the camera transform.
When I try to make a non-tracked object follow (with lag) a tracked object with a similar piece of code (same coroutine system), it DOES work perfectly. However, when I apply my code (coroutine) directly (as above) to the tracking: nothing changes. The object moves in "real time" despite the "custom" tracking, as if I did not tweak anything.
My question is then: has anyone already played with the SteamVR tracking and/or can anyone point me what I am missing ? Or maybe there is an other way to cheat the tracking system of a VR headset ?
Cheers,
KdRWaylander
We had a hard time figuring this out until we saw your simple explanation! We are working on an experiment at our university for a course, so with the deadline approaching we thought we wouldn't make it. Thank you so much!
Answer by KdRWaylander · Mar 13, 2018 at 12:12 PM
Here is the workaround I found (I was never able to tweak directly the tracking system):
I added an other camera with a higher depth and a target eye parameter set to "Both" in my scene. See this post that describes how to have 2 cameras in a scene.
I added a script on my new camera that makes the camera follow the SteamVR camera after a given amount of time (see below). This may be done differently (for exemple with a position buffer) and this may not be optimized but anyhow, it works.
I added the Tracked Pose Driver component (available since v2017.3 at least, maybe v2017.2) and then DISABLED IT. It is important to do so, this allows to make Unity understand that it must not override the position of the object (it seems to do so by default if there's a Camera component on the gameobject)
Lastly, i added the same Tracked Pose Driver component on the SteamVR camera (unless what nothing would move, I don't know why)
My follow script (C#):
using System.Collections.Generic;
using UnityEngine;
public class FollowWithLag : MonoBehaviour {
[SerializeField] Transform m_targetToFollow;
[SerializeField] bool m_lag;
[SerializeField] float m_lagTime;
Vector3 m_targetPosition;
Quaternion m_targetRotation;
void Update()
{
if (Input.GetKeyDown(KeyCode.L))
{
m_lag = !m_lag;
}
}
void LateUpdate ()
{
m_targetPosition = new Vector3(m_targetToFollow.position.x, m_targetToFollow.position.y, m_targetToFollow.position.z);
m_targetRotation = m_targetToFollow.transform.rotation;
if (m_lag && m_lagTime != 0)
{
StartCoroutine(LaggyFollow(m_targetPosition, m_targetRotation));
}
else if (!m_lag || m_lagTime == 0)
{
transform.position = m_targetPosition;
transform.rotation = m_targetRotation;
}
}
private IEnumerator LaggyFollow(Vector3 _pos, Quaternion _rot)
{
yield return new WaitForSeconds(m_lagTime/1000f);
transform.position = _pos;
transform.rotation = _rot;
}
}
Hope this helps someone one day.
Waylander
We had a hard time figuring this out until we saw your simple explanation! We are working on an experiment at our university for a course, so with the deadline approaching we thought we wouldn't make it. Thank you so much!
Can I supplement your answer? For the original camera, in the "camera" component, set the "culling mask" as "nothing" to improve performance.
Answer by yugen1 · Aug 04, 2020 at 08:57 AM
For people still looking at this issue, the script below does the lag part very efficiently
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraFollow : MonoBehaviour
{
public Transform mainCam; //this would be VR Camera or AR camera
public float delay = 0.5f;
public Camera camera; //this would be the 2nd added camera
private struct PointInSpace
{
public Vector3 Position;
public float Time;
}
private Queue<PointInSpace> pointsInSpace = new Queue<PointInSpace>();
void FixedUpdate()
{
// Add the current target position to the list of positions
pointsInSpace.Enqueue(new PointInSpace() { Position = mainCam.position, Time = Time.time });
// Move the camera to the position of the target X seconds ago
while (pointsInSpace.Count > 0 && pointsInSpace.Peek().Time <= Time.time - delay + Mathf.Epsilon)
{
transform.position = pointsInSpace.Dequeue().Position;
}
}
}
However, this works only in Unity editor for AR cases, which I am looking into. @KdRWaylander if you have any suggestion or idea please let us know.
Your answer
Follow this Question
Related Questions
Steam VR : Make latency 0 Answers
HTC Vive Camera Height [VRTK] [Steam VR] [Open VR] 1 Answer
Is it possible to access SteamVR settings with a script? 0 Answers
SteamVR 2.2 Change hand pose without interacting with an object 1 Answer
How do I switch levels when the user grabs an object in SteamVR? 0 Answers