Composite3DTileContent.js 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. import defaultValue from '../Core/defaultValue.js';
  2. import defined from '../Core/defined.js';
  3. import defineProperties from '../Core/defineProperties.js';
  4. import destroyObject from '../Core/destroyObject.js';
  5. import getMagic from '../Core/getMagic.js';
  6. import RuntimeError from '../Core/RuntimeError.js';
  7. import when from '../ThirdParty/when.js';
  8. /**
  9. * Represents the contents of a
  10. * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/specification/TileFormats/Composite|Composite}
  11. * tile in a {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/specification|3D Tiles} tileset.
  12. * <p>
  13. * Implements the {@link Cesium3DTileContent} interface.
  14. * </p>
  15. *
  16. * @alias Composite3DTileContent
  17. * @constructor
  18. *
  19. * @private
  20. */
  21. function Composite3DTileContent(tileset, tile, resource, arrayBuffer, byteOffset, factory) {
  22. this._tileset = tileset;
  23. this._tile = tile;
  24. this._resource = resource;
  25. this._contents = [];
  26. this._readyPromise = when.defer();
  27. initialize(this, arrayBuffer, byteOffset, factory);
  28. }
  29. defineProperties(Composite3DTileContent.prototype, {
  30. featurePropertiesDirty : {
  31. get : function() {
  32. var contents = this._contents;
  33. var length = contents.length;
  34. for (var i = 0; i < length; ++i) {
  35. if (contents[i].featurePropertiesDirty) {
  36. return true;
  37. }
  38. }
  39. return false;
  40. },
  41. set : function(value) {
  42. var contents = this._contents;
  43. var length = contents.length;
  44. for (var i = 0; i < length; ++i) {
  45. contents[i].featurePropertiesDirty = value;
  46. }
  47. }
  48. },
  49. /**
  50. * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code>
  51. * always returns <code>0</code>. Instead call <code>featuresLength</code> for a tile in the composite.
  52. * @memberof Composite3DTileContent.prototype
  53. */
  54. featuresLength : {
  55. get : function() {
  56. return 0;
  57. }
  58. },
  59. /**
  60. * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code>
  61. * always returns <code>0</code>. Instead call <code>pointsLength</code> for a tile in the composite.
  62. * @memberof Composite3DTileContent.prototype
  63. */
  64. pointsLength : {
  65. get : function() {
  66. return 0;
  67. }
  68. },
  69. /**
  70. * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code>
  71. * always returns <code>0</code>. Instead call <code>trianglesLength</code> for a tile in the composite.
  72. * @memberof Composite3DTileContent.prototype
  73. */
  74. trianglesLength : {
  75. get : function() {
  76. return 0;
  77. }
  78. },
  79. /**
  80. * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code>
  81. * always returns <code>0</code>. Instead call <code>geometryByteLength</code> for a tile in the composite.
  82. * @memberof Composite3DTileContent.prototype
  83. */
  84. geometryByteLength : {
  85. get : function() {
  86. return 0;
  87. }
  88. },
  89. /**
  90. * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code>
  91. * always returns <code>0</code>. Instead call <code>texturesByteLength</code> for a tile in the composite.
  92. * @memberof Composite3DTileContent.prototype
  93. */
  94. texturesByteLength : {
  95. get : function() {
  96. return 0;
  97. }
  98. },
  99. /**
  100. * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code>
  101. * always returns <code>0</code>. Instead call <code>batchTableByteLength</code> for a tile in the composite.
  102. * @memberof Composite3DTileContent.prototype
  103. */
  104. batchTableByteLength : {
  105. get : function() {
  106. return 0;
  107. }
  108. },
  109. innerContents : {
  110. get : function() {
  111. return this._contents;
  112. }
  113. },
  114. readyPromise : {
  115. get : function() {
  116. return this._readyPromise.promise;
  117. }
  118. },
  119. tileset : {
  120. get : function() {
  121. return this._tileset;
  122. }
  123. },
  124. tile : {
  125. get : function() {
  126. return this._tile;
  127. }
  128. },
  129. url : {
  130. get : function() {
  131. return this._resource.getUrlComponent(true);
  132. }
  133. },
  134. /**
  135. * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code>
  136. * always returns <code>undefined</code>. Instead call <code>batchTable</code> for a tile in the composite.
  137. * @memberof Composite3DTileContent.prototype
  138. */
  139. batchTable : {
  140. get : function() {
  141. return undefined;
  142. }
  143. }
  144. });
  145. var sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT;
  146. function initialize(content, arrayBuffer, byteOffset, factory) {
  147. byteOffset = defaultValue(byteOffset, 0);
  148. var uint8Array = new Uint8Array(arrayBuffer);
  149. var view = new DataView(arrayBuffer);
  150. byteOffset += sizeOfUint32; // Skip magic
  151. var version = view.getUint32(byteOffset, true);
  152. if (version !== 1) {
  153. throw new RuntimeError('Only Composite Tile version 1 is supported. Version ' + version + ' is not.');
  154. }
  155. byteOffset += sizeOfUint32;
  156. // Skip byteLength
  157. byteOffset += sizeOfUint32;
  158. var tilesLength = view.getUint32(byteOffset, true);
  159. byteOffset += sizeOfUint32;
  160. var contentPromises = [];
  161. for (var i = 0; i < tilesLength; ++i) {
  162. var tileType = getMagic(uint8Array, byteOffset);
  163. // Tile byte length is stored after magic and version
  164. var tileByteLength = view.getUint32(byteOffset + sizeOfUint32 * 2, true);
  165. var contentFactory = factory[tileType];
  166. if (defined(contentFactory)) {
  167. var innerContent = contentFactory(content._tileset, content._tile, content._resource, arrayBuffer, byteOffset);
  168. content._contents.push(innerContent);
  169. contentPromises.push(innerContent.readyPromise);
  170. } else {
  171. throw new RuntimeError('Unknown tile content type, ' + tileType + ', inside Composite tile');
  172. }
  173. byteOffset += tileByteLength;
  174. }
  175. when.all(contentPromises).then(function() {
  176. content._readyPromise.resolve(content);
  177. }).otherwise(function(error) {
  178. content._readyPromise.reject(error);
  179. });
  180. }
  181. /**
  182. * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code>
  183. * always returns <code>false</code>. Instead call <code>hasProperty</code> for a tile in the composite.
  184. */
  185. Composite3DTileContent.prototype.hasProperty = function(batchId, name) {
  186. return false;
  187. };
  188. /**
  189. * Part of the {@link Cesium3DTileContent} interface. <code>Composite3DTileContent</code>
  190. * always returns <code>undefined</code>. Instead call <code>getFeature</code> for a tile in the composite.
  191. */
  192. Composite3DTileContent.prototype.getFeature = function(batchId) {
  193. return undefined;
  194. };
  195. Composite3DTileContent.prototype.applyDebugSettings = function(enabled, color) {
  196. var contents = this._contents;
  197. var length = contents.length;
  198. for (var i = 0; i < length; ++i) {
  199. contents[i].applyDebugSettings(enabled, color);
  200. }
  201. };
  202. Composite3DTileContent.prototype.applyStyle = function(style) {
  203. var contents = this._contents;
  204. var length = contents.length;
  205. for (var i = 0; i < length; ++i) {
  206. contents[i].applyStyle(style);
  207. }
  208. };
  209. Composite3DTileContent.prototype.update = function(tileset, frameState) {
  210. var contents = this._contents;
  211. var length = contents.length;
  212. for (var i = 0; i < length; ++i) {
  213. contents[i].update(tileset, frameState);
  214. }
  215. };
  216. Composite3DTileContent.prototype.isDestroyed = function() {
  217. return false;
  218. };
  219. Composite3DTileContent.prototype.destroy = function() {
  220. var contents = this._contents;
  221. var length = contents.length;
  222. for (var i = 0; i < length; ++i) {
  223. contents[i].destroy();
  224. }
  225. return destroyObject(this);
  226. };
  227. export default Composite3DTileContent;