BinaryLoader.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. import * as THREE from "../../libs/three.js/build/three.module.js";
  2. import {Version} from "../Version.js";
  3. import {XHRFactory} from "../XHRFactory.js";
  4. export class BinaryLoader{
  5. constructor(version, boundingBox, scale){
  6. if (typeof (version) === 'string') {
  7. this.version = new Version(version);
  8. } else {
  9. this.version = version;
  10. }
  11. this.boundingBox = boundingBox;
  12. this.scale = scale;
  13. }
  14. load(node){
  15. if (node.loaded) {
  16. return;
  17. }
  18. let url = node.getURL();
  19. if (this.version.equalOrHigher('1.4')) {
  20. url += '.bin';
  21. }
  22. let xhr = XHRFactory.createXMLHttpRequest();
  23. xhr.open('GET', url, true);
  24. xhr.responseType = 'arraybuffer';
  25. xhr.overrideMimeType('text/plain; charset=x-user-defined');
  26. xhr.onreadystatechange = () => {
  27. if (xhr.readyState === 4) {
  28. if((xhr.status === 200 || xhr.status === 0) && xhr.response !== null){
  29. let buffer = xhr.response;
  30. this.parse(node, buffer);
  31. } else {
  32. //console.error(`Failed to load file! HTTP status: ${xhr.status}, file: ${url}`);
  33. throw new Error(`Failed to load file! HTTP status: ${xhr.status}, file: ${url}`);
  34. }
  35. }
  36. };
  37. try {
  38. xhr.send(null);
  39. } catch (e) {
  40. console.log('fehler beim laden der punktwolke: ' + e);
  41. }
  42. };
  43. parse(node, buffer){
  44. let pointAttributes = node.pcoGeometry.pointAttributes;
  45. let numPoints = buffer.byteLength / node.pcoGeometry.pointAttributes.byteSize;
  46. if (this.version.upTo('1.5')) {
  47. node.numPoints = numPoints;
  48. }
  49. let workerPath = Potree.scriptPath + '/workers/BinaryDecoderWorker.js';
  50. let worker = Potree.workerPool.getWorker(workerPath);
  51. worker.onmessage = function (e) {
  52. let data = e.data;
  53. let buffers = data.attributeBuffers;
  54. let tightBoundingBox = new THREE.Box3(
  55. new THREE.Vector3().fromArray(data.tightBoundingBox.min),
  56. new THREE.Vector3().fromArray(data.tightBoundingBox.max)
  57. );
  58. Potree.workerPool.returnWorker(workerPath, worker);
  59. let geometry = new THREE.BufferGeometry();
  60. for(let property in buffers){
  61. let buffer = buffers[property].buffer;
  62. let batchAttribute = buffers[property].attribute;
  63. if (property === "POSITION_CARTESIAN") {
  64. geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(buffer), 3));
  65. } else if (property === "rgba") {
  66. geometry.setAttribute("rgba", new THREE.BufferAttribute(new Uint8Array(buffer), 4, true));
  67. } else if (property === "NORMAL_SPHEREMAPPED") {
  68. geometry.setAttribute('normal', new THREE.BufferAttribute(new Float32Array(buffer), 3));
  69. } else if (property === "NORMAL_OCT16") {
  70. geometry.setAttribute('normal', new THREE.BufferAttribute(new Float32Array(buffer), 3));
  71. } else if (property === "NORMAL") {
  72. geometry.setAttribute('normal', new THREE.BufferAttribute(new Float32Array(buffer), 3));
  73. } else if (property === "INDICES") {
  74. let bufferAttribute = new THREE.BufferAttribute(new Uint8Array(buffer), 4);
  75. bufferAttribute.normalized = true;
  76. geometry.setAttribute('indices', bufferAttribute);
  77. } else if (property === "SPACING") {
  78. let bufferAttribute = new THREE.BufferAttribute(new Float32Array(buffer), 1);
  79. geometry.setAttribute('spacing', bufferAttribute);
  80. } else {
  81. const bufferAttribute = new THREE.BufferAttribute(new Float32Array(buffer), 1);
  82. bufferAttribute.potree = {
  83. offset: buffers[property].offset,
  84. scale: buffers[property].scale,
  85. preciseBuffer: buffers[property].preciseBuffer,
  86. range: batchAttribute.range,
  87. };
  88. geometry.setAttribute(property, bufferAttribute);
  89. const attribute = pointAttributes.attributes.find(a => a.name === batchAttribute.name);
  90. attribute.range[0] = Math.min(attribute.range[0], batchAttribute.range[0]);
  91. attribute.range[1] = Math.max(attribute.range[1], batchAttribute.range[1]);
  92. if(node.getLevel() === 0){
  93. attribute.initialRange = batchAttribute.range;
  94. }
  95. }
  96. }
  97. tightBoundingBox.max.sub(tightBoundingBox.min);
  98. tightBoundingBox.min.set(0, 0, 0);
  99. let numPoints = e.data.buffer.byteLength / pointAttributes.byteSize;
  100. node.numPoints = numPoints;
  101. node.geometry = geometry;
  102. node.mean = new THREE.Vector3(...data.mean);
  103. node.tightBoundingBox = tightBoundingBox;
  104. node.loaded = true;
  105. node.loading = false;
  106. node.estimatedSpacing = data.estimatedSpacing;
  107. Potree.numNodesLoading--;
  108. };
  109. let message = {
  110. buffer: buffer,
  111. pointAttributes: pointAttributes,
  112. version: this.version.version,
  113. min: [ node.boundingBox.min.x, node.boundingBox.min.y, node.boundingBox.min.z ],
  114. offset: [node.pcoGeometry.offset.x, node.pcoGeometry.offset.y, node.pcoGeometry.offset.z],
  115. scale: this.scale,
  116. spacing: node.spacing,
  117. hasChildren: node.hasChildren,
  118. name: node.name
  119. };
  120. worker.postMessage(message, [message.buffer]);
  121. };
  122. }