Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Web Worker support #8

Closed
sguimmara opened this issue Sep 26, 2024 · 8 comments
Closed

Web Worker support #8

sguimmara opened this issue Sep 26, 2024 · 8 comments

Comments

@sguimmara
Copy link

Currently, AFAIK it is not possible to use copc.js with workers without some form of hack.

The most performance critical part seems to be the LAZ decompression (namely Las.PointData.decompressChunk()). This could very easily be done in a worker while keeping the API almost identical.

I could try to setup a rough PR for discussion if you'd like.

@connormanning
Copy link
Owner

I'm not quite sure what you mean - both viewer.copc.io and the Potree implementation for COPC/EPT use copc.js via web workers to decompress LAZ data without anything hacky going on.

Can you be more specific with exactly what you are trying to accomplish and what issue you are running into?

@sguimmara
Copy link
Author

Can you be more specific with exactly what you are trying to accomplish and what issue you are running into?

I'm implementing COPC support for the web library Giro3D.

I would like to move the laz decompression part in a worker. The decompression occurs in Copc.loadPointDataBuffer(), but I don't see how I could inject the worker logic so that the Las.PointData.decompressChunk() happens in a worker.

@connormanning
Copy link
Owner

connormanning commented Sep 26, 2024

All of the functions here are part of the public API. If you'd like to pull them apart and run some of those parts in a web worker, you can do so. This library provides building blocks and utility functions (and also works in NodeJS), so putting implementation details of composable functions into web workers would probably be out of scope here.

For example, in Potree we pass a compressed LAZ buffer received from the fetch API into a worker, where we decompress it and create a View of it, and then extract the data into GL-compatible buffers.

If you specifically want Las.PointData.decompressChunk() to happen in a worker, with the goal of achieving the functionality of Copc.loadPointDataBuffer(), then you can see here that you can use the existing API to do something like this:

function mainThreadStuff() {
  // Here you would already have the COPC metadata, LAS header, node you wish to fetch, etc.
  const compressed = await Copc.loadCompressedPointDataBuffer(filename, node)
  someWorker.postMessage({ compressed, header, node }, [compressed])
}

// Worker code.
function decompress(event) {
  const { compressed, header, node } = event.data
  const { pointDataRecordFormat, pointDataRecordLength } = header
  const { pointCount } = node

  const decompressed = Las.PointData.decompressChunk(
    compressed,
    { pointCount, pointDataRecordFormat, pointDataRecordLength },
    lazPerf
  )
  postMessage(decompressed, [decompressed])
}

I just typed this up now as pseudo-code so do not expect it to work - but hopefully it demonstrates my point: that the building blocks you need to accomplish this via web worker are already part of the public API.

@sguimmara
Copy link
Author

Thanks ! I'll try that and inform how it goes

@sguimmara
Copy link
Author

sguimmara commented Sep 26, 2024

loadCompressedPointDataBuffer() is not part of the public API AFAIK. It is not exported in the Copc object:

export const Copc = {
  create,
  loadHierarchyPage,
  loadPointDataBuffer,
  loadPointDataView,
}

That's why I couldn't "inject" my worker.

If it were part of the public API, that would be great :)

@connormanning
Copy link
Owner

That's true, it's such a light wrapper that I probably wasn't sure it was worth exposing - since it's just a range fetch. So a more accurate code sample would use your COPC getter:

  const { pointDataOffset, pointDataLength } = node
  const compressed = await get(pointDataOffset, pointDataOffset + pointDataLength)

But that can absolutely be added to the public API - no objections to that.

@connormanning
Copy link
Owner

Added, and published to npm as current latest version 0.0.7.

@sguimmara
Copy link
Author

Thanks for your quick response !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants