Skip to content

Commit bf38a72

Browse files
committedMar 11, 2024·
fix(PointCloud): fix precision error for entwinePointTileLayer
(cherry picked from commit 7eaff5c)
1 parent 06c7181 commit bf38a72

File tree

6 files changed

+34
-30
lines changed

6 files changed

+34
-30
lines changed
 

‎src/Layer/EntwinePointTileLayer.js

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class EntwinePointTileLayer extends PointCloudLayer {
4747
constructor(id, config) {
4848
super(id, config);
4949
this.isEntwinePointTileLayer = true;
50+
this.scale = new THREE.Vector3(1, 1, 1);
5051

5152
const resolve = this.addInitializationStep();
5253
this.whenReady = this.source.whenReady.then(() => {

‎src/Parser/LASLoader.js

+7-3
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,16 @@ class LASLoader {
7171
*/
7272
const scanAngles = new Float32Array(view.pointCount);
7373

74+
// For precision we take the first point that will be use as origin for a local referentiel.
75+
const origin = getPosition.map(f => f(0)).map(val => Math.floor(val));
76+
7477
for (let i = 0; i < view.pointCount; i++) {
7578
// `getPosition` apply scale and offset transform to the X, Y, Z
7679
// values. See https://github.com/connormanning/copc.js/blob/master/src/las/extractor.ts.
7780
const [x, y, z] = getPosition.map(f => f(i));
78-
positions[i * 3] = x;
79-
positions[i * 3 + 1] = y;
80-
positions[i * 3 + 2] = z;
81+
positions[i * 3] = x - origin[0];
82+
positions[i * 3 + 1] = y - origin[1];
83+
positions[i * 3 + 2] = z - origin[2];
8184

8285
intensities[i] = getIntensity(i);
8386
returnNumbers[i] = getReturnNumber(i);
@@ -115,6 +118,7 @@ class LASLoader {
115118
pointSourceID: pointSourceIDs,
116119
color: colors,
117120
scanAngle: scanAngles,
121+
origin,
118122
};
119123
}
120124

‎src/Parser/LASParser.js

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ export default {
7373
geometry.setAttribute('scanAngle', scanAngle);
7474

7575
geometry.computeBoundingBox();
76+
geometry.userData.origin = new THREE.Vector3().fromArray(attributes.origin);
7677
return geometry;
7778
});
7879
},

‎src/Parser/PotreeBinParser.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as THREE from 'three';
22

33
// See the different constants holding ordinal, name, numElements, byteSize in PointAttributes.cpp in PotreeConverter
44
// elementByteSize is byteSize / numElements
5-
const POINT_ATTTRIBUTES = {
5+
const POINT_ATTRIBUTES = {
66
POSITION_CARTESIAN: {
77
numElements: 3,
88
arrayType: Float32Array,
@@ -49,8 +49,8 @@ const POINT_ATTTRIBUTES = {
4949
},
5050
};
5151

52-
for (const potreeName of Object.keys(POINT_ATTTRIBUTES)) {
53-
const attr = POINT_ATTTRIBUTES[potreeName];
52+
for (const potreeName of Object.keys(POINT_ATTRIBUTES)) {
53+
const attr = POINT_ATTRIBUTES[potreeName];
5454
attr.potreeName = potreeName;
5555
attr.numByte = attr.numByte || attr.arrayType.BYTES_PER_ELEMENT;
5656
attr.byteSize = attr.numElements * attr.numByte;
@@ -81,15 +81,15 @@ export default {
8181
// Format: X1,Y1,Z1,R1,G1,B1,A1,[...],XN,YN,ZN,RN,GN,BN,AN
8282
let pointByteSize = 0;
8383
for (const potreeName of options.in.pointAttributes) {
84-
pointByteSize += POINT_ATTTRIBUTES[potreeName].byteSize;
84+
pointByteSize += POINT_ATTRIBUTES[potreeName].byteSize;
8585
}
8686
const numPoints = Math.floor(buffer.byteLength / pointByteSize);
8787

8888
const geometry = new THREE.BufferGeometry();
8989
let elemOffset = 0;
9090
let attrOffset = 0;
9191
for (const potreeName of options.in.pointAttributes) {
92-
const attr = POINT_ATTTRIBUTES[potreeName];
92+
const attr = POINT_ATTRIBUTES[potreeName];
9393
const arrayLength = attr.numElements * numPoints;
9494
const array = new attr.arrayType(arrayLength);
9595
for (let arrayOffset = 0; arrayOffset < arrayLength; arrayOffset += attr.numElements) {

‎src/Provider/PointCloudProvider.js

+2-4
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,8 @@ export default {
3636
addPickingAttribute(points);
3737
points.frustumCulled = false;
3838
points.matrixAutoUpdate = false;
39-
if (!layer.isEntwinePointTileLayer) {
40-
points.position.copy(node.bbox.min);
41-
points.scale.copy(layer.scale);
42-
}
39+
points.position.copy(geometry.userData.origin || node.bbox.min);
40+
points.scale.copy(layer.scale);
4341
points.updateMatrix();
4442
points.tightbbox = geometry.boundingBox.applyMatrix4(points.matrix);
4543
points.layer = layer;

‎test/unit/lasparser.js

+18-18
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ describe('LASParser', function () {
2626
assert.strictEqual(bufferGeometry.attributes.classification.count, bufferGeometry.userData.pointCount);
2727
assert.strictEqual(bufferGeometry.attributes.color, undefined);
2828

29-
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.min.x, bufferGeometry.userData.min[0], 0.1));
30-
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.min.y, bufferGeometry.userData.min[1], 0.1));
31-
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.min.z, bufferGeometry.userData.min[2], 0.1));
32-
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.max.x, bufferGeometry.userData.max[0], 0.1));
33-
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.max.y, bufferGeometry.userData.max[1], 0.1));
34-
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.max.z, bufferGeometry.userData.max[2], 0.1));
29+
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.min.x + bufferGeometry.userData.origin.x, bufferGeometry.userData.min[0], 0.1));
30+
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.min.y + bufferGeometry.userData.origin.y, bufferGeometry.userData.min[1], 0.1));
31+
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.min.z + bufferGeometry.userData.origin.z, bufferGeometry.userData.min[2], 0.1));
32+
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.max.x + bufferGeometry.userData.origin.x, bufferGeometry.userData.max[0], 0.1));
33+
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.max.y + bufferGeometry.userData.origin.y, bufferGeometry.userData.max[1], 0.1));
34+
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.max.z + bufferGeometry.userData.origin.z, bufferGeometry.userData.max[2], 0.1));
3535
});
3636

3737
describe('parses a laz file to a THREE.BufferGeometry', function () {
@@ -43,12 +43,12 @@ describe('LASParser', function () {
4343
assert.strictEqual(bufferGeometry.attributes.classification.count, bufferGeometry.userData.pointCount);
4444
assert.strictEqual(bufferGeometry.attributes.color, undefined);
4545

46-
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.min.x, bufferGeometry.userData.min[0], 0.1));
47-
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.min.y, bufferGeometry.userData.min[1], 0.1));
48-
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.min.z, bufferGeometry.userData.min[2], 0.1));
49-
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.max.x, bufferGeometry.userData.max[0], 0.1));
50-
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.max.y, bufferGeometry.userData.max[1], 0.1));
51-
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.max.z, bufferGeometry.userData.max[2], 0.1));
46+
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.min.x + bufferGeometry.userData.origin.x, bufferGeometry.userData.min[0], 0.1));
47+
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.min.y + bufferGeometry.userData.origin.y, bufferGeometry.userData.min[1], 0.1));
48+
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.min.z + bufferGeometry.userData.origin.z, bufferGeometry.userData.min[2], 0.1));
49+
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.max.x + bufferGeometry.userData.origin.x, bufferGeometry.userData.max[0], 0.1));
50+
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.max.y + bufferGeometry.userData.origin.y, bufferGeometry.userData.max[1], 0.1));
51+
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.max.z + bufferGeometry.userData.origin.z, bufferGeometry.userData.max[2], 0.1));
5252
});
5353

5454
it('laz v1.4', async () => {
@@ -59,12 +59,12 @@ describe('LASParser', function () {
5959
assert.strictEqual(bufferGeometry.attributes.classification.count, bufferGeometry.userData.pointCount);
6060
assert.strictEqual(bufferGeometry.attributes.color.count, bufferGeometry.userData.pointCount);
6161

62-
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.min.x, bufferGeometry.userData.min[0], 0.1));
63-
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.min.y, bufferGeometry.userData.min[1], 0.1));
64-
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.min.z, bufferGeometry.userData.min[2], 0.1));
65-
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.max.x, bufferGeometry.userData.max[0], 0.1));
66-
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.max.y, bufferGeometry.userData.max[1], 0.1));
67-
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.max.z, bufferGeometry.userData.max[2], 0.1));
62+
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.min.x + bufferGeometry.userData.origin.x, bufferGeometry.userData.min[0], 0.1));
63+
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.min.y + bufferGeometry.userData.origin.y, bufferGeometry.userData.min[1], 0.1));
64+
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.min.z + bufferGeometry.userData.origin.z, bufferGeometry.userData.min[2], 0.1));
65+
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.max.x + bufferGeometry.userData.origin.x, bufferGeometry.userData.max[0], 0.1));
66+
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.max.y + bufferGeometry.userData.origin.y, bufferGeometry.userData.max[1], 0.1));
67+
assert.ok(compareWithEpsilon(bufferGeometry.boundingBox.max.z + bufferGeometry.userData.origin.z, bufferGeometry.userData.max[2], 0.1));
6868
});
6969
});
7070
});

0 commit comments

Comments
 (0)
Please sign in to comment.