BinaryDecoderWorker.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913
  1. //import * as THREE from "../../libs/three.js/build/three.module.js";
  2. import {Version} from "../Version.js";
  3. import {PointAttributes, PointAttribute, PointAttributeTypes} from "../loader/PointAttributes.js";
  4. const typedArrayMapping = {
  5. "int8": Int8Array,
  6. "int16": Int16Array,
  7. "int32": Int32Array,
  8. "int64": Float64Array,
  9. "uint8": Uint8Array,
  10. "uint16": Uint16Array,
  11. "uint32": Uint32Array,
  12. "uint64": Float64Array,
  13. "float": Float32Array,
  14. "double": Float64Array,
  15. };
  16. const gs3dProplist = [
  17. 'f_dc_0', //color
  18. 'f_dc_1',
  19. 'f_dc_2',
  20. 'f_rest_0', // has sh if not null at origin inriav1parser.js
  21. 'f_rest_1',
  22. 'f_rest_2',
  23. 'f_rest_3',
  24. 'f_rest_4',
  25. 'f_rest_5',
  26. 'f_rest_6',
  27. 'f_rest_7',
  28. 'f_rest_8',
  29. 'f_rest_9',
  30. 'f_rest_10',
  31. 'f_rest_11',
  32. 'f_rest_12',
  33. 'f_rest_13',
  34. 'f_rest_14',
  35. 'f_rest_15',
  36. 'f_rest_16',
  37. 'f_rest_17',
  38. 'f_rest_18',
  39. 'f_rest_19',
  40. 'f_rest_20',
  41. 'f_rest_21',
  42. 'f_rest_22',
  43. 'f_rest_23',
  44. 'f_rest_24',
  45. 'f_rest_25',
  46. 'f_rest_26',
  47. 'f_rest_27',
  48. 'f_rest_28',
  49. 'f_rest_29',
  50. 'f_rest_30',
  51. 'f_rest_31',
  52. 'f_rest_32',
  53. 'f_rest_33',
  54. 'f_rest_34',
  55. 'f_rest_35',
  56. 'f_rest_36',
  57. 'f_rest_37',
  58. 'f_rest_38',
  59. 'f_rest_39',
  60. 'f_rest_40',
  61. 'f_rest_41',
  62. 'f_rest_42',
  63. 'f_rest_43',
  64. 'f_rest_44',
  65. 'opacity',
  66. 'scale_0',
  67. 'scale_1',
  68. 'scale_2',
  69. 'rot_0',
  70. 'rot_1',
  71. 'rot_2',
  72. 'rot_3'
  73. ]
  74. let clamp = function ( value, min, max ) {
  75. return Math.max( min, Math.min( max, value ) );
  76. }
  77. class Vector3 {
  78. constructor( x = 0, y = 0, z = 0 ) {
  79. Object.defineProperty( this, 'isVector3', { value: true } );
  80. this.x = x;
  81. this.y = y;
  82. this.z = z;
  83. }
  84. set( x, y, z ) {
  85. if ( z === undefined ) z = this.z; // sprite.scale.set(x,y)
  86. this.x = x;
  87. this.y = y;
  88. this.z = z;
  89. return this;
  90. }
  91. }
  92. class Quaternion {
  93. constructor( x = 0, y = 0, z = 0, w = 1 ) {
  94. Object.defineProperty( this, 'isQuaternion', { value: true } );
  95. this._x = x;
  96. this._y = y;
  97. this._z = z;
  98. this._w = w;
  99. }
  100. set( x, y, z, w ) {
  101. this._x = x;
  102. this._y = y;
  103. this._z = z;
  104. this._w = w;
  105. //this._onChangeCallback();
  106. return this;
  107. }
  108. }
  109. const _zero = new Vector3( 0, 0, 0 );
  110. const _one = new Vector3( 1, 1, 1 );
  111. class Matrix4 {
  112. constructor() {
  113. Object.defineProperty( this, 'isMatrix4', { value: true } );
  114. this.elements = [
  115. 1, 0, 0, 0,
  116. 0, 1, 0, 0,
  117. 0, 0, 1, 0,
  118. 0, 0, 0, 1
  119. ];
  120. if ( arguments.length > 0 ) {
  121. console.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );
  122. }
  123. }
  124. makeRotationFromQuaternion( q ) {
  125. return this.compose( _zero, q, _one );
  126. }
  127. compose( position, quaternion, scale ) {
  128. const te = this.elements;
  129. const x = quaternion._x, y = quaternion._y, z = quaternion._z, w = quaternion._w;
  130. const x2 = x + x, y2 = y + y, z2 = z + z;
  131. const xx = x * x2, xy = x * y2, xz = x * z2;
  132. const yy = y * y2, yz = y * z2, zz = z * z2;
  133. const wx = w * x2, wy = w * y2, wz = w * z2;
  134. const sx = scale.x, sy = scale.y, sz = scale.z;
  135. te[ 0 ] = ( 1 - ( yy + zz ) ) * sx;
  136. te[ 1 ] = ( xy + wz ) * sx;
  137. te[ 2 ] = ( xz - wy ) * sx;
  138. te[ 3 ] = 0;
  139. te[ 4 ] = ( xy - wz ) * sy;
  140. te[ 5 ] = ( 1 - ( xx + zz ) ) * sy;
  141. te[ 6 ] = ( yz + wx ) * sy;
  142. te[ 7 ] = 0;
  143. te[ 8 ] = ( xz + wy ) * sz;
  144. te[ 9 ] = ( yz - wx ) * sz;
  145. te[ 10 ] = ( 1 - ( xx + yy ) ) * sz;
  146. te[ 11 ] = 0;
  147. te[ 12 ] = position.x;
  148. te[ 13 ] = position.y;
  149. te[ 14 ] = position.z;
  150. te[ 15 ] = 1;
  151. return this;
  152. }
  153. makeScale( x, y, z ) {
  154. this.set(
  155. x, 0, 0, 0,
  156. 0, y, 0, 0,
  157. 0, 0, z, 0,
  158. 0, 0, 0, 1
  159. );
  160. return this;
  161. }
  162. set( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
  163. const te = this.elements;
  164. te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;
  165. te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;
  166. te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;
  167. te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;
  168. return this;
  169. }
  170. }
  171. class Matrix3 {
  172. constructor() {
  173. Object.defineProperty( this, 'isMatrix3', { value: true } );
  174. this.elements = [
  175. 1, 0, 0,
  176. 0, 1, 0,
  177. 0, 0, 1
  178. ];
  179. if ( arguments.length > 0 ) {
  180. console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );
  181. }
  182. }
  183. copy( m ) {
  184. const te = this.elements;
  185. const me = m.elements;
  186. te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ];
  187. te[ 3 ] = me[ 3 ]; te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ];
  188. te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; te[ 8 ] = me[ 8 ];
  189. return this;
  190. }
  191. multiply( m ) {
  192. return this.multiplyMatrices( this, m );
  193. }
  194. premultiply( m ) {
  195. return this.multiplyMatrices( m, this );
  196. }
  197. multiplyMatrices( a, b ) {
  198. const ae = a.elements;
  199. const be = b.elements;
  200. const te = this.elements;
  201. const a11 = ae[ 0 ], a12 = ae[ 3 ], a13 = ae[ 6 ];
  202. const a21 = ae[ 1 ], a22 = ae[ 4 ], a23 = ae[ 7 ];
  203. const a31 = ae[ 2 ], a32 = ae[ 5 ], a33 = ae[ 8 ];
  204. const b11 = be[ 0 ], b12 = be[ 3 ], b13 = be[ 6 ];
  205. const b21 = be[ 1 ], b22 = be[ 4 ], b23 = be[ 7 ];
  206. const b31 = be[ 2 ], b32 = be[ 5 ], b33 = be[ 8 ];
  207. te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31;
  208. te[ 3 ] = a11 * b12 + a12 * b22 + a13 * b32;
  209. te[ 6 ] = a11 * b13 + a12 * b23 + a13 * b33;
  210. te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31;
  211. te[ 4 ] = a21 * b12 + a22 * b22 + a23 * b32;
  212. te[ 7 ] = a21 * b13 + a22 * b23 + a23 * b33;
  213. te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31;
  214. te[ 5 ] = a31 * b12 + a32 * b22 + a33 * b32;
  215. te[ 8 ] = a31 * b13 + a32 * b23 + a33 * b33;
  216. return this;
  217. }
  218. setFromMatrix4( m ) {
  219. const me = m.elements;
  220. this.set(
  221. me[ 0 ], me[ 4 ], me[ 8 ],
  222. me[ 1 ], me[ 5 ], me[ 9 ],
  223. me[ 2 ], me[ 6 ], me[ 10 ]
  224. );
  225. return this;
  226. }
  227. set( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {
  228. const te = this.elements;
  229. te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;
  230. te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;
  231. te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;
  232. return this;
  233. }
  234. transpose() {
  235. let tmp;
  236. const m = this.elements;
  237. tmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;
  238. tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;
  239. tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;
  240. return this;
  241. }
  242. }
  243. let toHalfFloat = function ( val ) {
  244. // Source: http://gamedev.stackexchange.com/questions/17326/conversion-of-a-number-from-single-precision-floating-point-representation-to-a/17410#17410
  245. /* This method is faster than the OpenEXR implementation (very often
  246. * used, eg. in Ogre), with the additional benefit of rounding, inspired
  247. * by James Tursa?s half-precision code. */
  248. _floatView[ 0 ] = val;
  249. const x = _int32View[ 0 ];
  250. let bits = ( x >> 16 ) & 0x8000; /* Get the sign */
  251. let m = ( x >> 12 ) & 0x07ff; /* Keep one extra bit for rounding */
  252. const e = ( x >> 23 ) & 0xff; /* Using int is faster here */
  253. /* If zero, or denormal, or exponent underflows too much for a denormal
  254. * half, return signed zero. */
  255. if ( e < 103 ) return bits;
  256. /* If NaN, return NaN. If Inf or exponent overflow, return Inf. */
  257. if ( e > 142 ) {
  258. bits |= 0x7c00;
  259. /* If exponent was 0xff and one mantissa bit was set, it means NaN,
  260. * not Inf, so make sure we set one mantissa bit too. */
  261. bits |= ( ( e == 255 ) ? 0 : 1 ) && ( x & 0x007fffff );
  262. return bits;
  263. }
  264. /* If exponent underflows but not too much, return a denorma l */
  265. if ( e < 113 ) {
  266. m |= 0x0800;
  267. /* Extra rounding may overflow and set mantissa to 0 and exponent
  268. * to 1, which is OK. */
  269. bits |= ( m >> ( 114 - e ) ) + ( ( m >> ( 113 - e ) ) & 1 );
  270. return bits;
  271. }
  272. bits |= ( ( e - 112 ) << 10 ) | ( m >> 1 );
  273. /* Extra rounding. An overflow will set mantissa to 0 and increment
  274. * the exponent, which is OK. */
  275. bits += m & 1;
  276. return bits;
  277. }
  278. let computeCovariance = function() {//通过旋转和缩放计算协方差(决定姿态)得到6个数
  279. const tempMatrix4 = new Matrix4();
  280. const scaleMatrix = new Matrix3();
  281. const rotationMatrix = new Matrix3();
  282. const covarianceMatrix = new Matrix3();
  283. const transformedCovariance = new Matrix3();
  284. const transform3x3 = new Matrix3();
  285. const transform3x3Transpose = new Matrix3();
  286. const thf = toHalfFloat //THREE.DataUtils.toHalfFloat.bind(THREE.DataUtils);
  287. return function(scale, rotation, transform, outCovariance, outOffset = 0, desiredOutputCompressionLevel) {
  288. tempMatrix4.makeScale(scale.x, scale.y, scale.z);
  289. scaleMatrix.setFromMatrix4(tempMatrix4);
  290. tempMatrix4.makeRotationFromQuaternion(rotation);
  291. rotationMatrix.setFromMatrix4(tempMatrix4);
  292. covarianceMatrix.copy(rotationMatrix).multiply(scaleMatrix);
  293. transformedCovariance.copy(covarianceMatrix).transpose().premultiply(covarianceMatrix); //为什么要乘以自己的转置呀?
  294. if (transform) {//场景的整体transform 如果可能移动就不传,在sort时直接乘
  295. transform3x3.setFromMatrix4(transform);
  296. transform3x3Transpose.copy(transform3x3).transpose();
  297. transformedCovariance.multiply(transform3x3Transpose);
  298. transformedCovariance.premultiply(transform3x3);
  299. }
  300. if (desiredOutputCompressionLevel === 1) {//压缩
  301. outCovariance[outOffset] = thf(transformedCovariance.elements[0]);
  302. outCovariance[outOffset + 1] = thf(transformedCovariance.elements[3]);
  303. outCovariance[outOffset + 2] = thf(transformedCovariance.elements[6]);
  304. outCovariance[outOffset + 3] = thf(transformedCovariance.elements[4]);
  305. outCovariance[outOffset + 4] = thf(transformedCovariance.elements[7]);
  306. outCovariance[outOffset + 5] = thf(transformedCovariance.elements[8]);
  307. } else {
  308. outCovariance[outOffset] = transformedCovariance.elements[0];
  309. outCovariance[outOffset + 1] = transformedCovariance.elements[3];
  310. outCovariance[outOffset + 2] = transformedCovariance.elements[6];
  311. outCovariance[outOffset + 3] = transformedCovariance.elements[4];
  312. outCovariance[outOffset + 4] = transformedCovariance.elements[7];
  313. outCovariance[outOffset + 5] = transformedCovariance.elements[8];
  314. }
  315. /*
  316. Vrk 中的元素分别是transformedCovariance的 [
  317. 0,3,6,
  318. 3,4,7,
  319. 6,7,8
  320. ]
  321. */
  322. };
  323. }();
  324. Potree = {};
  325. onmessage = function (event) {
  326. performance.mark("binary-decoder-start");
  327. let buffer = event.data.buffer;
  328. let pointAttributes = event.data.pointAttributes;
  329. let numPoints = buffer.byteLength / pointAttributes.byteSize;
  330. let view = new DataView(buffer);
  331. let version = new Version(event.data.version);
  332. let nodeOffset = event.data.offset;
  333. let scale = event.data.scale;
  334. let spacing = event.data.spacing;
  335. let hasChildren = event.data.hasChildren;
  336. let name = event.data.name;
  337. let tightBoxMin = [ Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY ];
  338. let tightBoxMax = [ Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY ];
  339. let mean = [0, 0, 0];
  340. let pos = event.data.min // add geometryNode.sceneNode.position node的偏移
  341. let attributeBuffers = {};
  342. let inOffset = 0;
  343. let hasGS3D = pointAttributes.attributes.some(e=>e.name == 'GS3D')
  344. for (let pointAttribute of pointAttributes.attributes) {
  345. if (pointAttribute.name === "POSITION_CARTESIAN") {
  346. let buff = new ArrayBuffer(numPoints * 4 * 3);
  347. let positions = new Float32Array(buff);
  348. for (let j = 0; j < numPoints; j++) {
  349. let x, y, z;
  350. if (version.newerThan('1.3')) {
  351. x = (view.getUint32(inOffset + j * pointAttributes.byteSize + 0, true) * scale);
  352. y = (view.getUint32(inOffset + j * pointAttributes.byteSize + 4, true) * scale);
  353. z = (view.getUint32(inOffset + j * pointAttributes.byteSize + 8, true) * scale);
  354. } else {
  355. x = view.getFloat32(j * pointAttributes.byteSize + 0, true) + nodeOffset[0];
  356. y = view.getFloat32(j * pointAttributes.byteSize + 4, true) + nodeOffset[1];
  357. z = view.getFloat32(j * pointAttributes.byteSize + 8, true) + nodeOffset[2];
  358. }
  359. positions[3 * j + 0] = x;
  360. positions[3 * j + 1] = y;
  361. positions[3 * j + 2] = z;
  362. mean[0] += x / numPoints;
  363. mean[1] += y / numPoints;
  364. mean[2] += z / numPoints;
  365. tightBoxMin[0] = Math.min(tightBoxMin[0], x);
  366. tightBoxMin[1] = Math.min(tightBoxMin[1], y);
  367. tightBoxMin[2] = Math.min(tightBoxMin[2], z);
  368. tightBoxMax[0] = Math.max(tightBoxMax[0], x);
  369. tightBoxMax[1] = Math.max(tightBoxMax[1], y);
  370. tightBoxMax[2] = Math.max(tightBoxMax[2], z);
  371. }
  372. attributeBuffers[pointAttribute.name] = { buffer: buff, attribute: pointAttribute };
  373. if(hasGS3D){//add
  374. let buff2 = new ArrayBuffer(numPoints * 4 * 4);
  375. let buff3 = new ArrayBuffer(numPoints * 4 * 3);
  376. let centersInt = new Int32Array(buff2);
  377. let centersFloat = new Float32Array(buff3);
  378. for(let i=0;i<numPoints;i++){
  379. centersFloat[3 * i + 0] = positions[3 * i + 0] + pos[0]
  380. centersFloat[3 * i + 1] = positions[3 * i + 1] + pos[1]
  381. centersFloat[3 * i + 2] = positions[3 * i + 2] + pos[2]
  382. //centersFloat[4 * i + 3] = 1;
  383. centersInt[4 * i + 0] = centersFloat[3 * i + 0] * 1000
  384. centersInt[4 * i + 1] = centersFloat[3 * i + 1] * 1000
  385. centersInt[4 * i + 2] = centersFloat[3 * i + 2] * 1000
  386. centersInt[4 * i + 3] = 1000
  387. }
  388. attributeBuffers['centersInt'] = { buffer: buff2, attribute: pointAttribute };
  389. attributeBuffers['centersFloat'] = { buffer: buff3, attribute: pointAttribute };
  390. }
  391. } else if (pointAttribute.name === "rgba") {
  392. let buff = new ArrayBuffer(numPoints * 4);
  393. let colors = new Uint8Array(buff);
  394. for (let j = 0; j < numPoints; j++) {
  395. colors[4 * j + 0] = view.getUint8(inOffset + j * pointAttributes.byteSize + 0);
  396. colors[4 * j + 1] = view.getUint8(inOffset + j * pointAttributes.byteSize + 1);
  397. colors[4 * j + 2] = view.getUint8(inOffset + j * pointAttributes.byteSize + 2);
  398. }
  399. attributeBuffers[pointAttribute.name] = { buffer: buff, attribute: pointAttribute };
  400. } else if (pointAttribute.name === "NORMAL_SPHEREMAPPED") {
  401. let buff = new ArrayBuffer(numPoints * 4 * 3);
  402. let normals = new Float32Array(buff);
  403. for (let j = 0; j < numPoints; j++) {
  404. let bx = view.getUint8(inOffset + j * pointAttributes.byteSize + 0);
  405. let by = view.getUint8(inOffset + j * pointAttributes.byteSize + 1);
  406. let ex = bx / 255;
  407. let ey = by / 255;
  408. let nx = ex * 2 - 1;
  409. let ny = ey * 2 - 1;
  410. let nz = 1;
  411. let nw = -1;
  412. let l = (nx * (-nx)) + (ny * (-ny)) + (nz * (-nw));
  413. nz = l;
  414. nx = nx * Math.sqrt(l);
  415. ny = ny * Math.sqrt(l);
  416. nx = nx * 2;
  417. ny = ny * 2;
  418. nz = nz * 2 - 1;
  419. normals[3 * j + 0] = nx;
  420. normals[3 * j + 1] = ny;
  421. normals[3 * j + 2] = nz;
  422. }
  423. attributeBuffers[pointAttribute.name] = { buffer: buff, attribute: pointAttribute };
  424. } else if (pointAttribute.name === "NORMAL_OCT16") {//只需要2 byte! 原本需要12个byte
  425. let buff = new ArrayBuffer(numPoints * 4 * 3);
  426. let normals = new Float32Array(buff);
  427. for (let j = 0; j < numPoints; j++) {
  428. let bx = view.getUint8(inOffset + j * pointAttributes.byteSize + 0);
  429. let by = view.getUint8(inOffset + j * pointAttributes.byteSize + 1);
  430. let u = (bx / 255) * 2 - 1;
  431. let v = (by / 255) * 2 - 1;
  432. let z = 1 - Math.abs(u) - Math.abs(v);
  433. let x = 0;
  434. let y = 0;
  435. if (z >= 0) {
  436. x = u;
  437. y = v;
  438. } else {
  439. x = -(v / Math.sign(v) - 1) / Math.sign(u);
  440. y = -(u / Math.sign(u) - 1) / Math.sign(v);
  441. }
  442. let length = Math.sqrt(x * x + y * y + z * z); //因法线长度固定为1,所以只需要xy就能算出z(不过这里似乎是约定相加为1?)
  443. x = x / length; //x和y都只有一个byte,所以精度很低,只有256个分段
  444. y = y / length;
  445. z = z / length;
  446. normals[3 * j + 0] = x;
  447. normals[3 * j + 1] = y;
  448. normals[3 * j + 2] = z;
  449. }
  450. attributeBuffers[pointAttribute.name] = { buffer: buff, attribute: pointAttribute };
  451. } else if (pointAttribute.name === "NORMAL") {
  452. let buff = new ArrayBuffer(numPoints * 4 * 3);
  453. let normals = new Float32Array(buff);
  454. for (let j = 0; j < numPoints; j++) {
  455. let x = view.getFloat32(inOffset + j * pointAttributes.byteSize + 0, true);
  456. let y = view.getFloat32(inOffset + j * pointAttributes.byteSize + 4, true);
  457. let z = view.getFloat32(inOffset + j * pointAttributes.byteSize + 8, true);
  458. normals[3 * j + 0] = x;
  459. normals[3 * j + 1] = y;
  460. normals[3 * j + 2] = z;
  461. }
  462. attributeBuffers[pointAttribute.name] = { buffer: buff, attribute: pointAttribute };
  463. }else if (pointAttribute.name === "IR" || pointAttribute.name === "TEMP" ) { //温度 ir是热成像的温度 temp是AI识别的温度
  464. let buff = new ArrayBuffer(numPoints * 4); //原本数据是uint16但是shader没办法接收,只能转了
  465. let f32 = new Float32Array(buff); //according to pointAttribute.type.name, 取值范围为 0 到 65535。
  466. let min = Infinity, max = -Infinity, v
  467. for (let j = 0; j < numPoints; j++) {//仿照position的写法 填入数据
  468. f32[j] = v = view.getUint16(inOffset + j * pointAttributes.byteSize, true) / 10 //开尔文
  469. v != 0 && (min = Math.min(min, v)) //==0可能是没探测到所以跳过
  470. v != 0 && (max = Math.max(max, v))
  471. }//ir or temp 里面的值除以10就是开尔文温度
  472. attributeBuffers[pointAttribute.name] = { buffer: buff, attribute: pointAttribute };
  473. pointAttribute.range = [min, max]; //但每个geo范围不一样
  474. }else if (pointAttribute.name === "SEG"){ //类型
  475. /*
  476. 1: concrete
  477. 2: wood
  478. 3: metal
  479. 4: glass
  480. 5: plastic
  481. 6: electric_wire
  482. */
  483. let buff = new ArrayBuffer(numPoints * 4);
  484. let f32 = new Float32Array(buff); //according to pointAttribute.type.name, 取值范围为 0 到 65535。
  485. for (let j = 0; j < numPoints; j++) {//仿照position的写法 填入数据
  486. f32[j] = view.getUint16(inOffset + j * pointAttributes.byteSize, true)
  487. }//ir or temp 里面的值除以10就是开尔文温度哈
  488. attributeBuffers[pointAttribute.name] = { buffer: buff, attribute: pointAttribute };
  489. } else if (pointAttribute.name === "GS3D") {//add 见inriav1plyparser.js
  490. //////////////////////////////////////////////////////////
  491. let buff = new ArrayBuffer(numPoints * pointAttribute.byteSize);
  492. let f32 = new Float32Array(buff);
  493. for (let j = 0; j < numPoints; j++) {//仿照position的写法 填入数据
  494. for (let i = 0; i < pointAttribute.numElements; i++) {
  495. //f32[pointAttribute.numElements * j + i] = view.getUint32( inOffset + j * pointAttributes.byteSize + 4*i, true) * scale ;
  496. f32[pointAttribute.numElements * j + i] = view.getFloat32(inOffset + j * pointAttributes.byteSize + 4*i, true) //+ nodeOffset[0];
  497. //是Uint32还是Float32? PlyParserUtils.js中写的是getFloat32 ( rawVertex[fieldId] = vertexData.getFloat32(offset + fieldOffsets[fieldId], true);)
  498. }
  499. }
  500. attributeBuffers[pointAttribute.name] = { buffer: buff, attribute: pointAttribute };
  501. //得到颜色
  502. let buff2 = new ArrayBuffer(numPoints * 4);
  503. let colors = new Uint8Array(buff2);
  504. const SH_C0 = 0.28209479177387814;
  505. const offset_opa = gs3dProplist.indexOf('opacity')
  506. const offset_col = gs3dProplist.indexOf('f_dc_0')
  507. let getColor = (index)=>{
  508. let value = (0.5 + SH_C0 * f32[index+offset_col]) * 255;
  509. return clamp(Math.floor(value), 0, 255);
  510. }
  511. let getOpacity = (index)=>{
  512. let value = (1 / (1 + Math.exp(-f32[index+offset_opa]))) * 255;
  513. return clamp(Math.floor(value), 0, 255);
  514. }
  515. for (let j = 0; j < numPoints; j++) {
  516. colors[4 * j + 0] = getColor(j * pointAttribute.numElements + 0)
  517. colors[4 * j + 1] = getColor(j * pointAttribute.numElements + 1)
  518. colors[4 * j + 2] = getColor(j * pointAttribute.numElements + 2)
  519. colors[4 * j + 3] = getOpacity(j * pointAttribute.numElements)
  520. }
  521. attributeBuffers['rgba'] = { buffer: buff2, attribute: pointAttribute };
  522. //compute cov:
  523. let buff3 = new ArrayBuffer(numPoints * 24);
  524. let covs = new Float32Array(buff3);
  525. const offset_scale = gs3dProplist.indexOf('scale_0') //第49个数开始是
  526. const offset_rot = gs3dProplist.indexOf('rot_0')
  527. let scale = new Vector3()
  528. let quaternion = new Quaternion()
  529. let getScale = (index)=>{
  530. let get = (offset)=>{
  531. return Math.exp(f32[index * pointAttribute.numElements + offset + offset_scale]);
  532. }
  533. scale.set(get(0), get(1), get(2))
  534. }
  535. let getQuatenion = (index)=>{
  536. let get = (offset)=>{
  537. return f32[index * pointAttribute.numElements + offset + offset_rot]
  538. }
  539. //quaternion.set( get(0), get(1), get(2), get(3))
  540. quaternion.set(get(1), get(2), get(3), get(0)) //w放到最后 另外如果compressionLevel不是0的话还要再加一步,见this.fbf(sectionFloatArray[rotationBase + 1]
  541. //quaternion.normalize();
  542. }
  543. for (let j = 0; j < numPoints; j++) {
  544. getScale(j);
  545. getQuatenion(j);
  546. computeCovariance(scale, quaternion, null, covs, 6 * j );
  547. }
  548. attributeBuffers['covs'] = { buffer: buff3, attribute: pointAttribute };
  549. //sh
  550. if(0){
  551. let sh = Potree.settings.splatSH
  552. let maxRest = 3 * ((sh+1)*(sh+1) - 1) //sh=2时要24个数
  553. let buff = new ArrayBuffer(numPoints * maxRest*4);
  554. //let shArray = new Float32Array(buff);
  555. let subArray
  556. const offset = gs3dProplist.indexOf('f_rest_0')
  557. for (let j = 0; j < numPoints; j++) {
  558. //let destView = shArray.subarray(j*maxRest, maxRest);
  559. let byteOffset = 4*j*maxRest
  560. let destView = new Float32Array(buff, byteOffset , maxRest);
  561. let start = j * pointAttribute.numElements+offset
  562. subArray = f32.subarray(start, start+maxRest);
  563. destView.set(subArray)
  564. }
  565. attributeBuffers['sh'] = { buffer: buff, attribute: pointAttribute };
  566. }
  567. ////////////////////////////////////////////////////////////////////////////////
  568. }else{
  569. let buff = new ArrayBuffer(numPoints * 4);
  570. let f32 = new Float32Array(buff);
  571. let TypedArray = typedArrayMapping[pointAttribute.type.name];
  572. preciseBuffer = new TypedArray(numPoints);
  573. let [min, max] = [Infinity, -Infinity];
  574. let [offset, scale] = [0, 1];
  575. const getterMap = {
  576. "int8": view.getInt8,
  577. "int16": view.getInt16,
  578. "int32": view.getInt32,
  579. "int64": view.getInt64,
  580. "uint8": view.getUint8,
  581. "uint16": view.getUint16,
  582. "uint32": view.getUint32,
  583. "uint64": view.getUint64,
  584. "float": view.getFloat32,
  585. "double": view.getFloat64,
  586. };
  587. const getter = getterMap[pointAttribute.type.name].bind(view);
  588. // compute offset and scale to pack larger types into 32 bit floats
  589. if(pointAttribute.type.size > 4){
  590. for(let j = 0; j < numPoints; j++){
  591. let value = getter(inOffset + j * pointAttributes.byteSize, true);
  592. if(!Number.isNaN(value)){
  593. min = Math.min(min, value);
  594. max = Math.max(max, value);
  595. }
  596. }
  597. if(pointAttribute.initialRange != null){
  598. offset = pointAttribute.initialRange[0];
  599. scale = 1 / (pointAttribute.initialRange[1] - pointAttribute.initialRange[0]);
  600. }else{
  601. offset = min;
  602. scale = 1 / (max - min);
  603. }
  604. }
  605. for(let j = 0; j < numPoints; j++){
  606. let value = getter(inOffset + j * pointAttributes.byteSize, true);
  607. if(!Number.isNaN(value)){
  608. min = Math.min(min, value);
  609. max = Math.max(max, value);
  610. }
  611. f32[j] = (value - offset) * scale;
  612. preciseBuffer[j] = value;
  613. }
  614. pointAttribute.range = [min, max];
  615. attributeBuffers[pointAttribute.name] = {
  616. buffer: buff,
  617. preciseBuffer: preciseBuffer,
  618. attribute: pointAttribute,
  619. offset: offset,
  620. scale: scale,
  621. };
  622. }
  623. inOffset += pointAttribute.byteSize;
  624. }
  625. { // add indices
  626. let buff = new ArrayBuffer(numPoints * 4);
  627. let indices = new Uint32Array(buff);
  628. for (let i = 0; i < numPoints; i++) {
  629. indices[i] = i;
  630. }
  631. attributeBuffers["INDICES"] = { buffer: buff, attribute: PointAttribute.INDICES };
  632. }
  633. { // handle attribute vectors
  634. let vectors = pointAttributes.vectors;
  635. for(let vector of vectors){
  636. let {name, attributes} = vector;
  637. let numVectorElements = attributes.length;
  638. let buffer = new ArrayBuffer(numVectorElements * numPoints * 4);
  639. let f32 = new Float32Array(buffer);
  640. let iElement = 0;
  641. for(let sourceName of attributes){
  642. let sourceBuffer = attributeBuffers[sourceName];
  643. let {offset, scale} = sourceBuffer;
  644. let view = new DataView(sourceBuffer.buffer);
  645. const getter = view.getFloat32.bind(view);
  646. for(let j = 0; j < numPoints; j++){
  647. let value = getter(j * 4, true);
  648. f32[j * numVectorElements + iElement] = (value / scale) + offset;
  649. }
  650. iElement++;
  651. }
  652. let vecAttribute = new PointAttribute(name, PointAttributeTypes.DATA_TYPE_FLOAT, 3);
  653. attributeBuffers[name] = {
  654. buffer: buffer,
  655. attribute: vecAttribute,
  656. };
  657. }
  658. }
  659. performance.mark("binary-decoder-end");
  660. // { // print timings
  661. // //performance.measure("spacing", "spacing-start", "spacing-end");
  662. // performance.measure("binary-decoder", "binary-decoder-start", "binary-decoder-end");
  663. // let measure = performance.getEntriesByType("measure")[0];
  664. // let dpp = 1000 * measure.duration / numPoints;
  665. // let pps = parseInt(numPoints / (measure.duration / 1000));
  666. // let debugMessage = `${measure.duration.toFixed(3)} ms, ${numPoints} points, ${pps.toLocaleString()} points/sec`;
  667. // console.log(debugMessage);
  668. // }
  669. performance.clearMarks();
  670. performance.clearMeasures();
  671. let message = {
  672. buffer: buffer,
  673. mean: mean,
  674. attributeBuffers: attributeBuffers,
  675. tightBoundingBox: { min: tightBoxMin, max: tightBoxMax },
  676. };
  677. let transferables = [];
  678. for (let property in message.attributeBuffers) {
  679. transferables.push(message.attributeBuffers[property].buffer);
  680. }
  681. transferables.push(buffer);
  682. postMessage(message, transferables);
  683. };