Skip to content

Commit

Permalink
feat(PointCloud): increase range of picking to u32
Browse files Browse the repository at this point in the history
  • Loading branch information
HoloTheDrunk committed Mar 13, 2024
1 parent 5d324ca commit 58a43d0
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 21 deletions.
1 change: 1 addition & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ The following people have contributed to iTowns.
* [Madec Germerie-Guizouarn](https://github.com/mgermerie)
* [Mathieu Brédif](https://github.com/mbredif)
* [Aymeric Dutremble](https://github.com/a-dutremble)
* [Raphaël Duhen](https://github.com/HoloTheDrunk)

* [CIRIL Group](https://www.cirilgroup.com/en/):
* [Vincent Jaillot](https://github.com/jailln)
Expand Down
6 changes: 3 additions & 3 deletions src/Core/Picking.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,11 @@ export default {

traversePickingCircle(radius, (x, y) => {
const idx = (y * 2 * radius + x) * 4;
const data = buffer.slice(idx, idx + 4);
const data = buffer.slice(idx, idx + 3);

// see PotreeProvider and the construction of unique_id
const objId = (data[0] << 8) | data[1];
const index = (data[2] << 8) | data[3];
const objId = data[0];
const index = (data[1] << 16) | data[2];

const r = { objId, index };

Expand Down
59 changes: 43 additions & 16 deletions src/Provider/PointCloudProvider.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,52 @@
import * as THREE from 'three';
import Extent from 'Core/Geographic/Extent';

const CLOUD_ID_WORD_COUNT = 1;
const MAX_CLOUDS = 2 ** (CLOUD_ID_WORD_COUNT * 16);

const POINT_ID_WORD_COUNT = 2;
const MAX_POINTS_PER_CLOUD = 2 ** (POINT_ID_WORD_COUNT * 16);

const ID_WORD_COUNT = POINT_ID_WORD_COUNT + CLOUD_ID_WORD_COUNT;

let nextuuid = 1;
/**
* Generate a unique ID for every point in a cloud.
* @param {THREE.Points} points - The point cloud to add IDs to.
* @returns {THREE.Points} The resulting point cloud.
*/
function addPickingAttribute(points) {
// generate unique id for picking
const numPoints = points.geometry.attributes.position.count;
const ids = new Uint8Array(4 * numPoints);
const baseId = nextuuid++;
if (numPoints > 0xffff || baseId > 0xffff) {
// TODO: fixme
console.warn('Currently picking is limited to Points with less than 65535 elements and less than 65535 Points instances');
const cloudId = nextuuid++;

if (
numPoints >= MAX_POINTS_PER_CLOUD ||
cloudId > MAX_CLOUDS
) {
console.warn(
`Too many points or clouds: ${numPoints} points and ${cloudId} clouds.\n` +
`Picking is currently limited to Points with less than ${MAX_POINTS_PER_CLOUD} elements and less than ${MAX_CLOUDS} Points instances`,
);
return points;
}
for (let i = 0; i < numPoints; i++) {
// todo numpoints > 16bits
const v = (baseId << 16) | i;
ids[4 * i + 0] = (v & 0xff000000) >> 24;
ids[4 * i + 1] = (v & 0x00ff0000) >> 16;
ids[4 * i + 2] = (v & 0x0000ff00) >> 8;
ids[4 * i + 3] = (v & 0x000000ff) >> 0;

// Generate and store an ID for every single point
const ids = new Uint16Array(ID_WORD_COUNT * numPoints);
for (let pointId = 0; pointId < numPoints; pointId++) {
// Full ID:
// word word word
// \__/ \_______/
// cloudId pointId
ids[ID_WORD_COUNT * pointId + 2] = pointId & 0x0000_ffff;
ids[ID_WORD_COUNT * pointId + 1] = (pointId & 0xffff_0000) >> 16;
ids[ID_WORD_COUNT * pointId] = cloudId;
}

points.baseId = baseId;
points.geometry.setAttribute('unique_id', new THREE.BufferAttribute(ids, 4, true));
points.baseId = cloudId;
points.geometry.setAttribute(
'unique_id',
new THREE.BufferAttribute(ids, 3, true),
);
return points;
}

Expand All @@ -41,7 +65,10 @@ export default {
points.updateMatrix();
points.tightbbox = geometry.boundingBox.applyMatrix4(points.matrix);
points.layer = layer;
points.extent = Extent.fromBox3(command.view.referenceCrs, node.bbox);
points.extent = Extent.fromBox3(
command.view.referenceCrs,
node.bbox,
);
points.userData.node = node;
return points;
});
Expand Down
4 changes: 2 additions & 2 deletions src/Renderer/Shader/PointsVS.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ uniform float maxAttenuatedSize;

attribute vec3 color;
attribute vec2 range;
attribute vec4 unique_id;
attribute vec3 unique_id;
attribute float intensity;
attribute float classification;
attribute float pointSourceID;
Expand Down Expand Up @@ -95,7 +95,7 @@ void main() {
#endif

if (picking) {
vColor = unique_id;
vColor = vec4(unique_id, 1.0);
} else {
vColor.a = opacity;
if (applyOpacityClassication || mode == PNTS_MODE_CLASSIFICATION) {
Expand Down

0 comments on commit 58a43d0

Please sign in to comment.