Can we reuse user`s VR boundaries?

Hi!

I would like to know if we can (and how :) ?) reuse the VR boundaries our VR user has to define before starting playing ?
So the Guardian for Quest users, and the play area for SteamVR users etc.

Ideally I would reuse these so my users don`t have to make a new one for my application...

What I`m looking for is like a flat geometry, or a curve? Or points and index so I can then generate something out of it..?

Also if anyone has reference of like other games/apps doing so I`d appreciate !

Thanks

1 Like

Yes!
XRInputSubsystem.TryGetBoundaryPoints returns a clockwise wound series of 3D positions whose height rests on the floor. You should be able to use that to generate a mesh.
Use XRInputSubsystem.boundaryChanged to listen for when the boundary gets updated (via Recenter or SDK adjustment), so you know when to regenerate the mesh.

You can get an XRInputSubsystem via SubsystemManager.GetInstances
Let me know if that helps.

5 Likes

Thank you this will come in very practical when its time comes ! :)

Do you have a tool in mind when it comes to procedurally model an environment depending on the Boundary Points?
I can think of Houdini but this won't be available at runtime.
Spline driven models that would use the Boundary points could get pretty advanced quickly, but I want to gain immersion by having some more variations on the wall so either edit this pline, either on the non reach-able parts (high building with different roofs setups etc.) To be short I'd like more than splined models. Tryin
I know a bit of Bolt I could try this in there, would you have anything easier in mind for achieving this or similar ?

Wow! Does this work with Oculus / Quest as is?

Yes!
But only in the new Plugin Architecture packages, Oculus was implemented in V1.0.0 of the package.

Hello guys !

I've been looking for a while after a solution for this.
I tried your method @StayTalm_Unity but i don't understand something. TryGetBoundaryPoints is a bool method, wich not send back any Vector3 stuff.

I also tried this method (and also lots of desperate things as retrieving the points directly from the Boundary Rendering gameobject) :

if (OVRManager.boundary.GetConfigured())
{
Vector3[ ] boundaryPosition = OVRManager.boundary.GetGeometry(OVRBoundary.BoundaryType.OuterBoundary);
}

But it keeps returning an empty array. I searched in the OVRBoundary code and don't get oculus devs logic.

If someone has some code to leak... ^^ it would help me!

If I further don't find a solution, I will try to change versions of oculus integration/packages/plugins/whatever..

Hey. I was trying the new API with Oculus Quest (mostly with Oculus Link, but I tested without Link as well),
and this function does not return any poits at all for me.
Since the API is new and I just started using it over the old OculusIntegration etc., I assume I’m missing something on my end.
What I’m trying is this:

    public void get_boundary_vertices()
    {
        List<XRInputSubsystem> subsystems = new List<XRInputSubsystem>();
        SubsystemManager.GetInstances<XRInputSubsystem>(subsystems);

        // make sure I actually have a subsystem loaded
        if (subsystems.Count > 0)
        {
            // create a List of Vec3 that will be filled with the vertices
            List<Vector3> boundaryPoints = new List<Vector3>();

            // if this returns true, then the subsystems supports a boundary and it should have filled our list with them
            if (subsystems[0].TryGetBoundaryPoints(boundaryPoints))
            {
                foreach (Vector3 pos in boundaryPoints)
                {
                    // TODO: do something sensible with the points, not this
                    Instantiate(GameObject.CreatePrimitive(PrimitiveType.Cube), pos, Quaternion.identity);
                }
            }
        }
    }

Since I’m chipping in here you might suspect: it does not work ^^ The TryGetBoundaryPoints function returns true, but the list remains empty.

  • The subsystems seems loaded correctly ( when stepping through I do get an “oculus input”)
  • it does not matter whether oculus Link is used or not
  • I’ve tried it with stationary boundary as well as a roomscale boundary setup
  • I thought maybe I need to call Start on the subsystem manually, but that did not do the trick
  • I am using the default 3D pipeline atm
  • other calls to the subsystem (i.e.GetTrackingOriginMode and GetSupportedTrackingOriginModes) return as expected

I might be missing something obvious, but so far this has brought me no luck.
The docs are sparse, in classic Unity fashion. ^^ The parameter is not explicitely declared and out param nor ref, so I’m not even sure this is how it is meant to work at this point!?

I saw another user ‘MrNorel’ in another forum thread say it worked for him with a slightly other way of getting to the subsystem, but trying that made no difference.
(this thread: https://discussions.unity.com/t/743301/9 )

If anyone has a working version or can tell me where I am going wrong, I would appreciate it :slight_smile:

3 Likes

@Enzo-z1 The bool that it returns, returns whether or not boundary points were successfully retrieved. This is important because there could be 0 points, but it can still have successfully got those 0 points, compared to some kind of internal failure to get points at all. The second benefit to this 'return value stating if function was a success, return data as paramters' pattern is that it can help you avoid heap allocations. You can reuse the same List and avoid creating new memory that needs to be almost immediately cleaned up because you specify which list to fill with data. If we returned a list, we couldn't let you supply a location in memory to put the boundary data.

That function expects a List to be passed in. That list gets filled with boundary points. So you would use it somewhat like this:

List<XRInputSubsystem> inputSubsystems = new List<XRInputSubsystem>();
SubsystemManager.GetInstances<XRInputSubsystem>(inputSubsystems);
if(inputSubsystems.Count > 0)
{
    List<Vector3> boundary = new List<Vector3>();
    if(inputSubsystems[0].TryGetBoundaryPoints(boundary))
    {
        // boundary is now filled with the current sequence of boundary points
    }
}

@StayTalm_Unity This doesn't appear to work at all with Quest + 2019.3.3 + v14 + XRPluginManagement/OculusLoader

I get one XRInputSubsystem (not much info on that object to debug, but I see it's reporting "Floor" mode, as expected), but zero points. I stuck it in Update to isolate any issues with startup/callbacks, and I just get neverendign "Nope, ther'es no boudnary", even when I can see it right in front of me :).

PS: I dislike the "if( success )" approach to API coding. It gives you no information about what the succes / failure was. If that's going to be in the final release, please could we upgrade to API's with a signature more like:

void TryThing( List preAllocList, out ErrorObjectOrNull );

...or go with the C# practice of throwing an exception on failure. Debugging in the presence of core methods that are returning "false" is a nightmare, especailly on larger projects.

2 Likes

This also doesn´t work for me. I work also with Quest, 2019.3.0f6 and the XRPlugin Managment System. I get an empty list … Do you have any suggestions or is this a known issue?

2 Likes

I guess: file a bug, with an empty project that has just one class that demonstrates the problem.

As far as I can tell, we're doing it right, it's just not working :)

1 Like

I read a bunch of posts and eventually pieced together the following solution.
Now I can create an outline of my outer boundary using a some primitives.

public GameObject wallMarker;
//Check if the boundary is configured
bool configured = OVRManager.boundary.GetConfigured();
        if (configured)
        {
            //Grab all the boundary points. Setting BoundaryType to OuterBoundary is necessary
            Vector3[] boundaryPoints = OVRManager.boundary.GetGeometry(OVRBoundary.BoundaryType.OuterBoundary);

             //Generate a bunch of tall thin cubes to mark the outline
            foreach (Vector3 pos in boundaryPoints)
            {     
                Instantiate(wallMarker, pos, Quaternion.identity);
            }
        }

Now I just need to figure out how to position the play area so that the created boundary is positioned correctly relative to the starting position of the player.
If anyone knows how to do that. Feel free to post it.

Edit: This is using Unity 2019.3.0f1 and building directly to a Quest

1 Like

That's using a different API though, and will only work for one headset / manufacturer, right?

i.e. it's not using the universal, cross-platform, API that most of us in this thread were trying to get working (which should work on all headest, from all manufacturers. In theory)

1 Like

Fair enough

When I was reading this I was thinking about building to Oculus, so I must have missed the part where this thread was supposed to be device agnostic.

@StayTalm_Unity same here, no points returned at all with TryGetBoundaryPoints. One subsystem found.
Unity 2019.3.10f1, XR Plugin Management 3.2.9, Oculus XR Plugin 1.3.3. Oculus Rift S as well as Quest+Link.

The "old" way of Oculus also does not return any points.

2 Likes

Hello! Does anyone know and is willing to explain how to convert these data from above posts to a Unity Spline ?
Thanks ! :)

Having the same issue have to build for the quest every time to test, no boundary data with the quest in link mode

1 Like

Same issue - 2019.3.13f1, XR Plugin Management 3.2.10, Oculus XR plugin 1.3.4.
no points returned (list count is zero). return value is true (indicating success). XR input subsystem is running. I've also tried polling it every second for the next minute (to see if it kicks into life) - no joy. Nothing fires the boundary changed callback.

1 Like