More robust three-mesh-bvh and batchedmesh integration

Hi Everyone,

I’m about to optimize parts of my code related to batchedmesh and mesh-bvh by adding workers. My devices are not very modern Samsung galaxy tabs, they can work hours a day with my code in the browser.

My journey is about to begin. Maybe my thoughts could be interesting to anyone here.

Subject: Bvh kernel for use in workers and main threads, as well for interchanging between threads.

At input it gets serialized unindexed geometry data, output is the serialized mesh-bvh spatial database.

Typical usage:

- Quickly deserialize built mesh-bvh in another thread for accelerated raycasting.

- Populate batched mesh from spatial clusters for accelerated per-cluster frustum culling.

Conflicting nature of raycasting and frustum culling:

- Single Bvh setup cannot be equally well for raycasting and frustum culling. Raycasting needs deeper depth with 10-20 tris per node. But frustum culling needs lesser node count.

- The bvh lib has computeBatchedBoundsTree that creates individual bvhs for subgeometries in a BatchedMesh. Not handy at thread-transfering and allocations.

- We had somewhat acceptable setup of single bvh for all, with clustering options set as maxtris=1k and maxdepth=10.

- May want to do separate bvh, one for culling, another for raycasting.

- Better fill BatchedMesh not from bvh leafs, but at some constant tree level above the leafs. This yields lesser number of batchlets of a larger size.

- Frustum culling in BatchedMesh is not accelerated with bvh nor extended by bvh lib as seen from BatchedMesh/onBeforeRender.

Worker support:

- Bvh lib has two kinds of worker GenerateMeshBVHWorker.js and ParallelMeshBVHWorker.js. It’s not added to the bvh library typings but can be done manually.

- We need own worker for other extra tasks, using individual workers is not great because it brings js machine with each.

Thread transfer:

- MeshBVH can be serialized and deserialized for transfer.

- BatchedMesh designed to copy sub-geometry data into its pre-allocated buffers. It cannot be easily transfered between threads.

- It lacks the ability to update its entire geometry externally without making completely separate subgeometries with own zero-based index.

- Take responsibility to make hack-batched-mesh to wrap original Batched mesh with desired short-way functions.

Minimizing allocations:

- Without modification of three-mesh-bvh very little can be done.

- There is no custom allocator as seen in buildPackedTree, the buffers there are created at each call.

- Thus it cannot rebuild its trees within the same buffer.

- It offers refit function that recomputes already established tree based on the same point index, assuming only coordinate values change. Topology index and vertex count must be same.

- Only attribute buffers in BufferGeometries can be reused.