gkjohnson / three-mesh-bvh

A BVH implementation to speed up raycasting and enable spatial queries against three.js meshes.
https://gkjohnson.github.io/three-mesh-bvh/example/bundle/raycast.html
MIT License
2.52k stars 265 forks source link

Add method to serialize to JSON #510

Closed neilrackett closed 1 year ago

neilrackett commented 1 year ago

Calculating BVH for a large model can take a very long time.

While it's currently possible to serialize BVH data into a format that can easily be transferred between workers and the main thread, it cannot easily be serialized into a format that can be exported as JSON, imported and deserialized later.

It would be great if you could do this:

const geometry = new THREE.TorusKnotGeometry( 10, 3, 100, 16 )
const bvh = new MeshBVH( geometry );
const json = MeshBVH.serializeJson( bvh );

// ... send to database (or add to GLTF extras?) for use later

const response = await fetch('bvh.json');
const json = await response.json();
const deserializedBVH = MeshBVH.deserializeJson( json, geometry );
geometry.boundsTree = deserializedBVH;

Possibly also useful as part of CLI tool suggestion (#367)?

gkjohnson commented 1 year ago

There are complexities in generating a BVH and storing in glTF which are outlined in #367, unfortunately. The serialized format is fairly simple, though, so implementing this at the app level should be straight forward - whether it be a file, database entry, browser cache storage, etc.

But either way I don't think JSON is an optimal format for storing the binary data required by the serialized format (file size, parse time). It would be best to save separate files or create a binary format to save the file to disk.

neilrackett commented 1 year ago

Thanks for the quick response - I'll investigate what we might be able to implement at app level as an alternative and let you know if we come up with anything useful!

gkjohnson commented 1 year ago

Sounds good -- I'll close this for now!

neilrackett commented 1 year ago

So, if you're looking to cache BVH and have just stumbled across this thread:

  1. While perhaps not optimal, JSON works surprisingly well, gzips nicely, requires no additional libraries and is easy to store, so here are some BVH-to-JSON tools you might find useful
  2. If you only need local browser caching, localForage can store a serialized BVH as-is, e.g. localForage.setItem("my-bvh", MeshBVH.serialize(bvh)) to save and geometry.boundsTree = MeshBVH.deserialize(await localForage.getItem("my-bvh"), geometry) to load