I talked some time ago about some work that has been needed to be done in Project Dasher – and other Forge viewer clients – in anticipation of supporting viewers such as Tandem’s. In this case it was fairly specifically about the need to support loading of multiple models inside the viewer, rather than working on the assumption that there’s a single model available.
For the last few days I’ve been looking at another area that by all accounts will be beneficial, whether driven by use of the Tandem viewer or the upcoming Forge viewer based on the latest Three.js version: I’ve gone through the codebase and replaced all use of THREE.Geometry with THREE.BufferGeometry. This has been motivated by the decision to completely drop support for the old THREE.Geometry implementation in Three.js. At some point (and possibly quite soon) it’ll be important to have done this work in Forge viewer applications using THREE.Geometry.
The work needed to start using THREE.BufferGeometry is reasonably straightforward: I found this guide to be quite useful. In general you need to collect your points, normals, etc. in arrays before using them to populate the BufferGeometry state. I’ve tended to use the handy setFromPoints() helper method for this, but have also used the lower-level setAttribute() method on occasion (for the latter you need a flat array of the point/normal/etc. coordinate values).
Inside Dasher I needed to migrate the following sub-components to use THREE.BufferGeometry:
- THREE.MeshLine
- This is used by a number of the following features.
- I chose to migrate the existing r71-supporting code rather than use a newer version.
- THREE.ArrowHelper
- We use this to display anemometer values, something I haven’t yet blogged about here.
- Streamlines
- This is our own version of the code that’s now built into the Forge viewer, so not strictly needed.
- Based on MeshLine.
- Skeletons
- Based on MeshLine.
- Robots
- Also needed work on the Collada loader.
Pretty much everything looks the same as it did, with the exception of robots. As you may remember, I made the decision to go with wireframe display of robots inside the Forge viewer, mainly because the rendering of materials didn’t work well with depthTest set to true. An unfortunate compromise, but not a huge issue.
This time around, though, I found that for the life of me I couldn’t get wireframe mode to work properly. In the end – out of sheer desperation – I switched to realistic (Phong) shading and set depthTest to true… and the results were stunning!
When animating I found I did have to call viewer.refresh(true) after modifying the robot’s geometry, but it still all worked with very decent performanvce.
It’s hard to know what has contributed to this now working: it could be performance improvements in the viewer, the use of THREE.BufferGeometry, or perhaps me making a silly mistake the last time around. Or all of the above. Whichever way I’m very happy with these results.
Next I’d like to find a way to detect when the robot is about to hit its surroundings – in this case the MX3D bridge – but it’s not at all sure that this is something that can be done without degrading performance significantly. We’ll see.