At the Forge Accelerator in Munich, back in December, while I spent most of my time answering what questions I could about Forge I also showed up with a question of my own.
In the original prototype of Dasher 360 we used code from a very helpful sample that showed how to add SVG markers to the DOM inside the Forge viewer. The original sample showed this in the context of adding markup to a model: on our side we wanted it to mark the location of sensors in the model. While this was great for small numbers of sensors, it didn’t really scale: not only did it get slow – each sensor needed its own set of DOM elements – but managing occlusion from existing model geometry proved to be really challenging.
So while Philippe Leefsma and I were sharing a taxi to the Accelerator’s location in Munich, we talked about this problem. Philippe’s suggestion was to make use of the capability in THREE.js to display point clouds. His big question was whether the version of THREE.js being used by the Forge viewer was recent enough for us to make use of this feature or not. My take was that should the viewer be using an older version of THREE.js, there’d be a strong case to be made for the viewer adopting a newer version: this was important to us, and I’m sure would be beneficial to other uses of the Forge viewer, too.
As it turned out – thanks to research performed by my colleague Simon Breslav – the version of THREE.js being used in the Forge viewer was recent enough to include the point cloud feature. Admittedly it’s an earlier version – in more recent versions of THREE.js it was renamed from PointCloud to ParticleSystem and then Points – but it works very well. What’s great is that Simon could use some of his shader-fu to create a custom GLSL shader to make the points look pretty much identical to the way they were in the previous implementation.
While I won’t share the code just yet (you’ll be able to view the page source once it’s been integrated into Dasher 360), here’s the basic approach:
- Define your vertex and fragment shaders in string variables (they should be implemented using GLSL).
- Create a THREE.ShaderMaterial with the two shaders as optio
- If you’re occluding with other geometry, set depthTest and depthWrite to true.
- Create a THREE.Geometry object and push your points to its vertices property.
- Create a THREE.PointCloud (later this will need migration to THREE.Points) with the geometry and material.
- Add this to the Forge viewer using viewer.impl.addOverlay() (you may need to call viewer.impl.invalidate() afterwards).
Here’s a quick screenshot of sensors being seen through the window of the 210 King Street East building. Navigation is now much, much smooth than with our previous attempt at implementing occlusion.
Having a single point cloud object does pose some challenges for various per-sensor features such as displaying tooltips and enabling “on click” selection, however. We had to jump through quite a few hoops to make it all work. In the next post I’ll share some details on how we did so.