智慧水务管理系统 - 精河县供水工程综合管理平台

GltfLoaderUtil.js 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. import Cartesian2 from "../Core/Cartesian2.js";
  2. import Check from "../Core/Check.js";
  3. import Frozen from "../Core/Frozen.js";
  4. import defined from "../Core/defined.js";
  5. import Matrix3 from "../Core/Matrix3.js";
  6. import Sampler from "../Renderer/Sampler.js";
  7. import TextureMagnificationFilter from "../Renderer/TextureMagnificationFilter.js";
  8. import TextureMinificationFilter from "../Renderer/TextureMinificationFilter.js";
  9. import TextureWrap from "../Renderer/TextureWrap.js";
  10. import ModelComponents from "./ModelComponents.js";
  11. /**
  12. * glTF loading utilities.
  13. *
  14. * @namespace GltfLoaderUtil
  15. *
  16. * @private
  17. */
  18. const GltfLoaderUtil = {};
  19. /**
  20. * Get the image ID referenced by a texture.
  21. * <p>
  22. * When the texture has the EXT_texture_webp extension and the browser supports
  23. * WebP images the WebP image ID is returned.
  24. * </p>
  25. *
  26. * @param {object} options Object with the following properties:
  27. * @param {object} options.gltf The glTF JSON.
  28. * @param {number} options.textureId The texture ID.
  29. * @param {SupportedImageFormats} options.supportedImageFormats The supported image formats.
  30. *
  31. * @returns {number} The image ID.
  32. * @private
  33. */
  34. GltfLoaderUtil.getImageIdFromTexture = function (options) {
  35. options = options ?? Frozen.EMPTY_OBJECT;
  36. const { gltf, textureId, supportedImageFormats } = options;
  37. //>>includeStart('debug', pragmas.debug);
  38. Check.typeOf.object("options.gltf", gltf);
  39. Check.typeOf.number("options.textureId", textureId);
  40. Check.typeOf.object("options.supportedImageFormats", supportedImageFormats);
  41. //>>includeEnd('debug');
  42. const texture = gltf.textures[textureId];
  43. const extensions = texture.extensions;
  44. if (defined(extensions)) {
  45. if (supportedImageFormats.webp && defined(extensions.EXT_texture_webp)) {
  46. return extensions.EXT_texture_webp.source;
  47. } else if (
  48. supportedImageFormats.basis &&
  49. defined(extensions.KHR_texture_basisu)
  50. ) {
  51. return extensions.KHR_texture_basisu.source;
  52. }
  53. }
  54. return texture.source;
  55. };
  56. /**
  57. * Create a sampler for a texture.
  58. *
  59. * @param {object} options Object with the following properties:
  60. * @param {object} options.gltf The glTF JSON.
  61. * @param {object} options.textureInfo The texture info object.
  62. * @param {boolean} [options.compressedTextureNoMipmap=false] True when the texture is compressed and does not have an embedded mipmap.
  63. *
  64. * @returns {Sampler} The sampler.
  65. * @private
  66. */
  67. GltfLoaderUtil.createSampler = function (options) {
  68. options = options ?? Frozen.EMPTY_OBJECT;
  69. const { gltf, textureInfo, compressedTextureNoMipmap = false } = options;
  70. //>>includeStart('debug', pragmas.debug);
  71. Check.typeOf.object("options.gltf", gltf);
  72. Check.typeOf.object("options.textureInfo", textureInfo);
  73. //>>includeEnd('debug');
  74. // Default sampler properties
  75. let wrapS = TextureWrap.REPEAT;
  76. let wrapT = TextureWrap.REPEAT;
  77. let minFilter = TextureMinificationFilter.LINEAR;
  78. let magFilter = TextureMagnificationFilter.LINEAR;
  79. const textureId = textureInfo.index;
  80. const texture = gltf.textures[textureId];
  81. const samplerId = texture.sampler;
  82. if (defined(samplerId)) {
  83. const sampler = gltf.samplers[samplerId];
  84. wrapS = sampler.wrapS ?? wrapS;
  85. wrapT = sampler.wrapT ?? wrapT;
  86. minFilter = sampler.minFilter ?? minFilter;
  87. magFilter = sampler.magFilter ?? magFilter;
  88. }
  89. if (
  90. compressedTextureNoMipmap &&
  91. minFilter !== TextureMinificationFilter.LINEAR &&
  92. minFilter !== TextureMinificationFilter.NEAREST
  93. ) {
  94. if (
  95. minFilter === TextureMinificationFilter.NEAREST_MIPMAP_NEAREST ||
  96. minFilter === TextureMinificationFilter.NEAREST_MIPMAP_LINEAR
  97. ) {
  98. minFilter = TextureMinificationFilter.NEAREST;
  99. } else {
  100. minFilter = TextureMinificationFilter.LINEAR;
  101. }
  102. }
  103. return new Sampler({
  104. wrapS: wrapS,
  105. wrapT: wrapT,
  106. minificationFilter: minFilter,
  107. magnificationFilter: magFilter,
  108. });
  109. };
  110. const defaultScale = new Cartesian2(1.0, 1.0);
  111. /**
  112. * Create a model texture reader.
  113. *
  114. * @param {object} options Object with the following properties:
  115. * @param {object} options.textureInfo The texture info JSON.
  116. * @param {string} [options.channels] The texture channels to read from.
  117. * @param {Texture} [options.texture] The texture object.
  118. *
  119. * @returns {ModelComponents.TextureReader} The texture reader for this model.
  120. */
  121. GltfLoaderUtil.createModelTextureReader = function (options) {
  122. options = options ?? Frozen.EMPTY_OBJECT;
  123. const { textureInfo, channels, texture } = options;
  124. //>>includeStart('debug', pragmas.debug);
  125. Check.typeOf.object("options.textureInfo", textureInfo);
  126. //>>includeEnd('debug');
  127. let texCoord = textureInfo.texCoord ?? 0;
  128. let transform;
  129. const textureTransform = textureInfo.extensions?.KHR_texture_transform;
  130. if (defined(textureTransform)) {
  131. texCoord = textureTransform.texCoord ?? texCoord;
  132. const offset = defined(textureTransform.offset)
  133. ? Cartesian2.unpack(textureTransform.offset)
  134. : Cartesian2.ZERO;
  135. let rotation = textureTransform.rotation ?? 0.0;
  136. const scale = defined(textureTransform.scale)
  137. ? Cartesian2.unpack(textureTransform.scale)
  138. : defaultScale;
  139. // glTF assumes UV coordinates start with (0, 0) in the top left corner
  140. // (y-down) unlike WebGL which puts (0, 0) in the bottom left corner (y-up).
  141. // This means rotations are reversed since the angle from x to y is now
  142. // clockwise instead of CCW. Translations and scales are not impacted by
  143. // this.
  144. rotation = -rotation;
  145. // prettier-ignore
  146. transform = new Matrix3(
  147. Math.cos(rotation) * scale.x, -Math.sin(rotation) * scale.y, offset.x,
  148. Math.sin(rotation) * scale.x, Math.cos(rotation) * scale.y, offset.y,
  149. 0.0, 0.0, 1.0
  150. );
  151. }
  152. const modelTextureReader = new ModelComponents.TextureReader();
  153. modelTextureReader.index = textureInfo.index;
  154. modelTextureReader.texture = texture;
  155. modelTextureReader.texCoord = texCoord;
  156. modelTextureReader.scale = textureInfo.scale;
  157. modelTextureReader.transform = transform;
  158. modelTextureReader.channels = channels;
  159. // EXT_textureInfo_constant_lod extension
  160. const constantLodExtension =
  161. textureInfo.extensions?.EXT_textureInfo_constant_lod;
  162. if (defined(constantLodExtension)) {
  163. modelTextureReader.constantLod = {
  164. repetitions: constantLodExtension.repetitions ?? 1.0,
  165. offset: defined(constantLodExtension.offset)
  166. ? Cartesian2.unpack(constantLodExtension.offset)
  167. : Cartesian2.ZERO,
  168. minClampDistance: constantLodExtension.minClampDistance ?? 1.0,
  169. maxClampDistance: constantLodExtension.maxClampDistance ?? 4294967296.0,
  170. };
  171. }
  172. return modelTextureReader;
  173. };
  174. export default GltfLoaderUtil;