Are boxes better than planes for VR gaze intersections?



This question is really for @dave, @max, or others that worked on the WebVR Lab project. I’ve been examining that project and I noticed that the VR intersection objects (floors, walls, etc.) were constructed using boxes scaled to 0.001 on one axis–essentially taking the shape of a plane.

I’m just wondering why? It seems like planes would be more performant, but I’m sure there’s a reason that you’re using boxes. :slight_smile: Do planes have a problem calculating correctly?



PlayCanvas doesn’t have bounding planes support yet :).


Actually, there is a Plane. @yaustar even improved it at some point, but for some reason it has “private” flag in docs so it not coming up in API Reference.

As you can see it has method intersectsRay. But, Planes are actually infinite, they have no borders. So what you really need is “3D Rectangle”.

I’ve created a ticket for this feature:


Ooooh, okay! Makes sense.

Thanks for the help and explanation guys!


Hey, so on a related note, is it possible to use an imported model as those collision surfaces?

For example, if the scene is complex (with varying wall angles, etc.) it can be pretty tedious to set up all of those collision boxes within the PlayCanvas editor. While totally workable, 3D navigation and positioning isn’t quite as comfortable as in an application like Maya or Blender. I’m wondering if there is a way for me to do this:

  1. Load up my scene in Maya/Blender (I already have an FBX of my scene)
  2. Create all of my collision walls as simple planes or boxes within Blender
  3. Export an FBX of just my collision walls
  4. Import that collision walls FBX into playcanvas
  5. Have it properly calculate the intersections based on the geometry I’m loading in

Is the current shape.js and shape-world.js setup for the WebVR Lab project easily adaptable to use this geometry method?


You can use an imported mesh as a ‘nav mesh’ ( IIRC, PlayCanvas doesn’t have an support for doing a raycast against a mesh without enabling physics (ammo.js in this case) which increases download size and may have some performance issues on mobile.

That said, you can write your own raycast method to test against an imported mesh which I think @Mr_F has done?


Oh okay! ‘Nav mesh’ is what it’s called; I wondered about that! :slight_smile:

Thanks for the info. I was worried that I’d need to enable physics for this. I’m a little hesitant to do that.

@Mr_F, do you have public projects that incorporate your custom raycast method? Or any thoughts that could point me in the right direction (even just links are welcome). I’m not really sure where to begin, but I’d love to learn.


NavMesh technically is an array of triangles. Really you need ray-triangle picking, and you are pretty much good to go.


In After the Flood I used a bruteforce navmesh approach, which means basically that I was snapping the player to a closest point of a closest triangle of the mesh. Because there weren’t too many triangles (around 200), I was simply checking every one. But ideally there had to be some optimization. I didn’t do any actual raycasts there, just finding the closest point. I can share the source if you need (and the project is gonna be released publicly soon anyway).

Here’s how it looked, basically represents all walkable space:

It’s like inverting the way you think of collisions. Instead of obstacles you work on paths.


Super interesting! I’d love to see the source for this, but I can wait until it’s released publicly.

Can you elaborate slightly on ‘snapping the player to the closest point’? The player, of course, isn’t actually sticking to each vertex–they’re able to move fluidly–so I don’t quite understand that. If you have time, I’d love to hear more. :smiley:



isn’t actually sticking to each vertex–they’re able to move fluidly

It’s finding the closest position on a closest triangle.


Oooh okay, I totally “read” your first post as “to a closest [vertex] of a closest triangle of the mesh”, whereas you actually meant the closest location on the triangle, not vertex. Got it! Thanks a ton for the help!