cesium icon indicating copy to clipboard operation
cesium copied to clipboard

Retrieve point cloud point positions on click

Open OmarShehata opened this issue 6 years ago • 7 comments

This is something that's come up a few times recently on the forum. There's some good discussion on it in these threads:

Yes we have the same issue. Our solution was to use a spatialite database to do a spatial query on the point cloud as this was able to bypass the screen-space inaccuracies and the fact that there's no GPU-CPU transfer of point cloud data. Obviously not ideal for many reasons, but it enabled us to show details for the exact location of a point. Omar, it's the definition of "exact" that's the issue. The buffer will get very close, but when dealing with point clouds with an accuracy of 1/10mm, the buffer isn't good enough. Plus it sometimes gives wildly inaccurate values if you're on the very edge of a point (in the order of hundreds of metres inaccurate).

Some notes from @lilleyse about how we could go about implementing this:

  • Does the data need to reside on the CPU or is it fast enough to do GPU copy with gl.bufferSubData? All point data is stored in vertex buffers.
  • If going with CPU approach, add an option that controls whether the data stays on the CPU. This is the line that normally deletes it: https://github.com/AnalyticalGraphicsInc/cesium/blob/master/Source/Scene/PointCloud.js#L1323.
  • Add an API for retrieving point data . Something imilar to Cesium3DTileFeature. The problem is we don't want to create a Cesium3DTileFeature per point, so we'll need something leaner.

OmarShehata avatar Jun 20 '19 21:06 OmarShehata

Just want to revise something I said. The buffer call is gl.getBufferSubData and is only available for webgl2. Instead we could store per point data in textures and use readPixels.

lilleyse avatar Jun 21 '19 11:06 lilleyse

This came up again on the forum here, specifically that you can't rely on scene.pickPosition to get point positions. This is reproduced in this Sandcastle. If you click on any point on the building, towards the horizon (such that the mountain is behind where you're clicking, but you're still clicking on the point cloud), you'll get a correct output like this:

Picked object {primitive: Cesium3DTileset, content: PointCloud3DTileContent}
Distance from known point 7.555343978706986

Where the "known point" is a point on this building. But sometimes, you'll get:

Picked object {primitive: Cesium3DTileset, content: PointCloud3DTileContent}
Distance from known point 19238.09656548114

So even though scene.pick knows you clicked on the point cloud, the pickPosition seems to click through and get a point far int he distance.

@lilleyse is there any known workaround for this, especially since scene.pick seems to correctly figure out you're clicking the point cloud?

OmarShehata avatar Dec 05 '19 16:12 OmarShehata

Changing scene.pick(mousePosition) to scene.pick(mousePosition, 1, 1); seems to at least make the results consistent (so if you click on the edge of attenuated point, pickPosition will pick a point in the distance, picking through the point cloud, but so will pick).

OmarShehata avatar Dec 08 '19 15:12 OmarShehata

Changing scene.pick(mousePosition) to scene.pick(mousePosition, 1, 1); seems to at least make the results consistent (so if you click on the edge of attenuated point, pickPosition will pick a point in the distance, picking through the point cloud, but so will pick).

That solved my problem. Thanks!

Edit: following up, just to say that now I use pick(mousePosition, 1, 1), check that I get a 3DTileset (primitive instanceof Cesium.Cesium3DTileset) and then call pickPosition with the same mouse position. Seems to be OK so far.

vhive-jonathan-carse avatar Dec 09 '19 11:12 vhive-jonathan-carse

The need to click on a point and get its position for drawing lines on a point cloud came up again here:

https://groups.google.com/d/msg/cesium-dev/tla7PUio2Ys/qSz1csvHAwAJ

OmarShehata avatar Mar 26 '20 13:03 OmarShehata

Hi! I am having the same issue on this. I am trying to only get the position inside the point cloud during left click. If I clicked on a less denser point cloud, I always get a position behind it. Is there any way to get the closest point in the point cloud based on the initial clicked position?

sarahmeh avatar Jul 20 '23 10:07 sarahmeh

Is there any way to get the closest point in the point cloud based on the initial clicked position?

@sarahmeh Have you tried using drillPick? Also, though it's private API, there is drillPickFromRayMostDetailed . From them, you get an array of picked points, and you can iterate over them to get the one closest to the camera. Both functions take a width parameter, which allows to pick not only the clicked pixel, but also around it.

anne-gropler avatar Jun 05 '24 08:06 anne-gropler