decodeDraco.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /* This file is automatically rebuilt by the Cesium build process. */
  2. define(['./defined-26bd4a03', './Check-da037458', './freezeObject-2d83f591', './defaultValue-f2e68450', './Math-fa6e45cb', './RuntimeError-ad75c885', './WebGLConstants-497deb20', './ComponentDatatype-69643096', './when-ee12a2cb', './IndexDatatype-3de60176', './createTaskProcessorWorker'], function (defined, Check, freezeObject, defaultValue, _Math, RuntimeError, WebGLConstants, ComponentDatatype, when, IndexDatatype, createTaskProcessorWorker) { 'use strict';
  3. /* global require */
  4. var draco;
  5. function decodeIndexArray(dracoGeometry, dracoDecoder) {
  6. var numPoints = dracoGeometry.num_points();
  7. var numFaces = dracoGeometry.num_faces();
  8. var faceIndices = new draco.DracoInt32Array();
  9. var numIndices = numFaces * 3;
  10. var indexArray = IndexDatatype.IndexDatatype.createTypedArray(numPoints, numIndices);
  11. var offset = 0;
  12. for (var i = 0; i < numFaces; ++i) {
  13. dracoDecoder.GetFaceFromMesh(dracoGeometry, i, faceIndices);
  14. indexArray[offset + 0] = faceIndices.GetValue(0);
  15. indexArray[offset + 1] = faceIndices.GetValue(1);
  16. indexArray[offset + 2] = faceIndices.GetValue(2);
  17. offset += 3;
  18. }
  19. draco.destroy(faceIndices);
  20. return {
  21. typedArray : indexArray,
  22. numberOfIndices : numIndices
  23. };
  24. }
  25. function decodeQuantizedDracoTypedArray(dracoGeometry, dracoDecoder, dracoAttribute, quantization, vertexArrayLength) {
  26. var vertexArray;
  27. var attributeData;
  28. if (quantization.quantizationBits <= 8) {
  29. attributeData = new draco.DracoUInt8Array();
  30. vertexArray = new Uint8Array(vertexArrayLength);
  31. dracoDecoder.GetAttributeUInt8ForAllPoints(dracoGeometry, dracoAttribute, attributeData);
  32. } else {
  33. attributeData = new draco.DracoUInt16Array();
  34. vertexArray = new Uint16Array(vertexArrayLength);
  35. dracoDecoder.GetAttributeUInt16ForAllPoints(dracoGeometry, dracoAttribute, attributeData);
  36. }
  37. for (var i = 0; i < vertexArrayLength; ++i) {
  38. vertexArray[i] = attributeData.GetValue(i);
  39. }
  40. draco.destroy(attributeData);
  41. return vertexArray;
  42. }
  43. function decodeDracoTypedArray(dracoGeometry, dracoDecoder, dracoAttribute, vertexArrayLength) {
  44. var vertexArray;
  45. var attributeData;
  46. // Some attribute types are casted down to 32 bit since Draco only returns 32 bit values
  47. switch (dracoAttribute.data_type()) {
  48. case 1: case 11: // DT_INT8 or DT_BOOL
  49. attributeData = new draco.DracoInt8Array();
  50. vertexArray = new Int8Array(vertexArrayLength);
  51. dracoDecoder.GetAttributeInt8ForAllPoints(dracoGeometry, dracoAttribute, attributeData);
  52. break;
  53. case 2: // DT_UINT8
  54. attributeData = new draco.DracoUInt8Array();
  55. vertexArray = new Uint8Array(vertexArrayLength);
  56. dracoDecoder.GetAttributeUInt8ForAllPoints(dracoGeometry, dracoAttribute, attributeData);
  57. break;
  58. case 3: // DT_INT16
  59. attributeData = new draco.DracoInt16Array();
  60. vertexArray = new Int16Array(vertexArrayLength);
  61. dracoDecoder.GetAttributeInt16ForAllPoints(dracoGeometry, dracoAttribute, attributeData);
  62. break;
  63. case 4: // DT_UINT16
  64. attributeData = new draco.DracoUInt16Array();
  65. vertexArray = new Uint16Array(vertexArrayLength);
  66. dracoDecoder.GetAttributeUInt16ForAllPoints(dracoGeometry, dracoAttribute, attributeData);
  67. break;
  68. case 5: case 7: // DT_INT32 or DT_INT64
  69. attributeData = new draco.DracoInt32Array();
  70. vertexArray = new Int32Array(vertexArrayLength);
  71. dracoDecoder.GetAttributeInt32ForAllPoints(dracoGeometry, dracoAttribute, attributeData);
  72. break;
  73. case 6: case 8: // DT_UINT32 or DT_UINT64
  74. attributeData = new draco.DracoUInt32Array();
  75. vertexArray = new Uint32Array(vertexArrayLength);
  76. dracoDecoder.GetAttributeUInt32ForAllPoints(dracoGeometry, dracoAttribute, attributeData);
  77. break;
  78. case 9: case 10: // DT_FLOAT32 or DT_FLOAT64
  79. attributeData = new draco.DracoFloat32Array();
  80. vertexArray = new Float32Array(vertexArrayLength);
  81. dracoDecoder.GetAttributeFloatForAllPoints(dracoGeometry, dracoAttribute, attributeData);
  82. break;
  83. }
  84. for (var i = 0; i < vertexArrayLength; ++i) {
  85. vertexArray[i] = attributeData.GetValue(i);
  86. }
  87. draco.destroy(attributeData);
  88. return vertexArray;
  89. }
  90. function decodeAttribute(dracoGeometry, dracoDecoder, dracoAttribute) {
  91. var numPoints = dracoGeometry.num_points();
  92. var numComponents = dracoAttribute.num_components();
  93. var quantization;
  94. var transform = new draco.AttributeQuantizationTransform();
  95. if (transform.InitFromAttribute(dracoAttribute)) {
  96. var minValues = new Array(numComponents);
  97. for (var i = 0; i < numComponents; ++i) {
  98. minValues[i] = transform.min_value(i);
  99. }
  100. quantization = {
  101. quantizationBits : transform.quantization_bits(),
  102. minValues : minValues,
  103. range : transform.range(),
  104. octEncoded : false
  105. };
  106. }
  107. draco.destroy(transform);
  108. transform = new draco.AttributeOctahedronTransform();
  109. if (transform.InitFromAttribute(dracoAttribute)) {
  110. quantization = {
  111. quantizationBits : transform.quantization_bits(),
  112. octEncoded : true
  113. };
  114. }
  115. draco.destroy(transform);
  116. var vertexArrayLength = numPoints * numComponents;
  117. var vertexArray;
  118. if (defined.defined(quantization)) {
  119. vertexArray = decodeQuantizedDracoTypedArray(dracoGeometry, dracoDecoder, dracoAttribute, quantization, vertexArrayLength);
  120. } else {
  121. vertexArray = decodeDracoTypedArray(dracoGeometry, dracoDecoder, dracoAttribute, vertexArrayLength);
  122. }
  123. var componentDatatype = ComponentDatatype.ComponentDatatype.fromTypedArray(vertexArray);
  124. return {
  125. array : vertexArray,
  126. data : {
  127. componentsPerAttribute : numComponents,
  128. componentDatatype : componentDatatype,
  129. byteOffset : dracoAttribute.byte_offset(),
  130. byteStride : ComponentDatatype.ComponentDatatype.getSizeInBytes(componentDatatype) * numComponents,
  131. normalized : dracoAttribute.normalized(),
  132. quantization : quantization
  133. }
  134. };
  135. }
  136. function decodePointCloud(parameters) {
  137. var dracoDecoder = new draco.Decoder();
  138. if (parameters.dequantizeInShader) {
  139. dracoDecoder.SkipAttributeTransform(draco.POSITION);
  140. dracoDecoder.SkipAttributeTransform(draco.NORMAL);
  141. }
  142. var buffer = new draco.DecoderBuffer();
  143. buffer.Init(parameters.buffer, parameters.buffer.length);
  144. var geometryType = dracoDecoder.GetEncodedGeometryType(buffer);
  145. if (geometryType !== draco.POINT_CLOUD) {
  146. throw new RuntimeError.RuntimeError('Draco geometry type must be POINT_CLOUD.');
  147. }
  148. var dracoPointCloud = new draco.PointCloud();
  149. var decodingStatus = dracoDecoder.DecodeBufferToPointCloud(buffer, dracoPointCloud);
  150. if (!decodingStatus.ok() || dracoPointCloud.ptr === 0) {
  151. throw new RuntimeError.RuntimeError('Error decoding draco point cloud: ' + decodingStatus.error_msg());
  152. }
  153. draco.destroy(buffer);
  154. var result = {};
  155. var properties = parameters.properties;
  156. for (var propertyName in properties) {
  157. if (properties.hasOwnProperty(propertyName)) {
  158. var attributeId = properties[propertyName];
  159. var dracoAttribute = dracoDecoder.GetAttributeByUniqueId(dracoPointCloud, attributeId);
  160. result[propertyName] = decodeAttribute(dracoPointCloud, dracoDecoder, dracoAttribute);
  161. }
  162. }
  163. draco.destroy(dracoPointCloud);
  164. draco.destroy(dracoDecoder);
  165. return result;
  166. }
  167. function decodePrimitive(parameters) {
  168. var dracoDecoder = new draco.Decoder();
  169. // Skip all parameter types except generic
  170. var attributesToSkip = ['POSITION', 'NORMAL', 'COLOR', 'TEX_COORD'];
  171. if (parameters.dequantizeInShader) {
  172. for (var i = 0; i < attributesToSkip.length; ++i) {
  173. dracoDecoder.SkipAttributeTransform(draco[attributesToSkip[i]]);
  174. }
  175. }
  176. var bufferView = parameters.bufferView;
  177. var buffer = new draco.DecoderBuffer();
  178. buffer.Init(parameters.array, bufferView.byteLength);
  179. var geometryType = dracoDecoder.GetEncodedGeometryType(buffer);
  180. if (geometryType !== draco.TRIANGULAR_MESH) {
  181. throw new RuntimeError.RuntimeError('Unsupported draco mesh geometry type.');
  182. }
  183. var dracoGeometry = new draco.Mesh();
  184. var decodingStatus = dracoDecoder.DecodeBufferToMesh(buffer, dracoGeometry);
  185. if (!decodingStatus.ok() || dracoGeometry.ptr === 0) {
  186. throw new RuntimeError.RuntimeError('Error decoding draco mesh geometry: ' + decodingStatus.error_msg());
  187. }
  188. draco.destroy(buffer);
  189. var attributeData = {};
  190. var compressedAttributes = parameters.compressedAttributes;
  191. for (var attributeName in compressedAttributes) {
  192. if (compressedAttributes.hasOwnProperty(attributeName)) {
  193. var compressedAttribute = compressedAttributes[attributeName];
  194. var dracoAttribute = dracoDecoder.GetAttributeByUniqueId(dracoGeometry, compressedAttribute);
  195. attributeData[attributeName] = decodeAttribute(dracoGeometry, dracoDecoder, dracoAttribute);
  196. }
  197. }
  198. var result = {
  199. indexArray : decodeIndexArray(dracoGeometry, dracoDecoder),
  200. attributeData : attributeData
  201. };
  202. draco.destroy(dracoGeometry);
  203. draco.destroy(dracoDecoder);
  204. return result;
  205. }
  206. function decode(parameters) {
  207. if (defined.defined(parameters.primitive)) {
  208. return decodePrimitive(parameters);
  209. }
  210. return decodePointCloud(parameters);
  211. }
  212. function initWorker(dracoModule) {
  213. draco = dracoModule;
  214. self.onmessage = createTaskProcessorWorker(decode);
  215. self.postMessage(true);
  216. }
  217. function decodeDraco(event) {
  218. var data = event.data;
  219. // Expect the first message to be to load a web assembly module
  220. var wasmConfig = data.webAssemblyConfig;
  221. if (defined.defined(wasmConfig)) {
  222. // Require and compile WebAssembly module, or use fallback if not supported
  223. return require([wasmConfig.modulePath], function(dracoModule) {
  224. if (defined.defined(wasmConfig.wasmBinaryFile)) {
  225. if (!defined.defined(dracoModule)) {
  226. dracoModule = self.DracoDecoderModule;
  227. }
  228. dracoModule(wasmConfig).then(function (compiledModule) {
  229. initWorker(compiledModule);
  230. });
  231. } else {
  232. initWorker(dracoModule());
  233. }
  234. });
  235. }
  236. }
  237. return decodeDraco;
  238. });