ForEach.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. import hasExtension from './hasExtension.js'
  2. import defined from '../../Core/defined.js'
  3. import isArray from '../../Core/isArray.js'
  4. /**
  5. * Contains traversal functions for processing elements of the glTF hierarchy.
  6. * @constructor
  7. *
  8. * @private
  9. */
  10. function ForEach() {
  11. }
  12. /**
  13. * Fallback for glTF 1.0
  14. * @private
  15. */
  16. ForEach.objectLegacy = function(objects, handler) {
  17. if (defined(objects)) {
  18. for (var objectId in objects) {
  19. if (Object.prototype.hasOwnProperty.call(objects, objectId)) {
  20. var object = objects[objectId];
  21. var value = handler(object, objectId);
  22. if (defined(value)) {
  23. return value;
  24. }
  25. }
  26. }
  27. }
  28. };
  29. /**
  30. * @private
  31. */
  32. ForEach.object = function(arrayOfObjects, handler) {
  33. if (defined(arrayOfObjects)) {
  34. var length = arrayOfObjects.length;
  35. for (var i = 0; i < length; i++) {
  36. var object = arrayOfObjects[i];
  37. var value = handler(object, i);
  38. if (defined(value)) {
  39. return value;
  40. }
  41. }
  42. }
  43. };
  44. /**
  45. * Supports glTF 1.0 and 2.0
  46. * @private
  47. */
  48. ForEach.topLevel = function(gltf, name, handler) {
  49. var gltfProperty = gltf[name];
  50. if (defined(gltfProperty) && !isArray(gltfProperty)) {
  51. return ForEach.objectLegacy(gltfProperty, handler);
  52. }
  53. return ForEach.object(gltfProperty, handler);
  54. };
  55. ForEach.accessor = function(gltf, handler) {
  56. return ForEach.topLevel(gltf, 'accessors', handler);
  57. };
  58. ForEach.accessorWithSemantic = function(gltf, semantic, handler) {
  59. var visited = {};
  60. return ForEach.mesh(gltf, function(mesh) {
  61. return ForEach.meshPrimitive(mesh, function(primitive) {
  62. var valueForEach = ForEach.meshPrimitiveAttribute(primitive, function(accessorId, attributeSemantic) {
  63. if (attributeSemantic.indexOf(semantic) === 0 && !defined(visited[accessorId])) {
  64. visited[accessorId] = true;
  65. var value = handler(accessorId);
  66. if (defined(value)) {
  67. return value;
  68. }
  69. }
  70. });
  71. if (defined(valueForEach)) {
  72. return valueForEach;
  73. }
  74. return ForEach.meshPrimitiveTarget(primitive, function(target) {
  75. return ForEach.meshPrimitiveTargetAttribute(target, function(accessorId, attributeSemantic) {
  76. if (attributeSemantic.indexOf(semantic) === 0 && !defined(visited[accessorId])) {
  77. visited[accessorId] = true;
  78. var value = handler(accessorId);
  79. if (defined(value)) {
  80. return value;
  81. }
  82. }
  83. });
  84. });
  85. });
  86. });
  87. };
  88. ForEach.accessorContainingVertexAttributeData = function(gltf, handler) {
  89. var visited = {};
  90. return ForEach.mesh(gltf, function(mesh) {
  91. return ForEach.meshPrimitive(mesh, function(primitive) {
  92. var valueForEach = ForEach.meshPrimitiveAttribute(primitive, function(accessorId) {
  93. if (!defined(visited[accessorId])) {
  94. visited[accessorId] = true;
  95. var value = handler(accessorId);
  96. if (defined(value)) {
  97. return value;
  98. }
  99. }
  100. });
  101. if (defined(valueForEach)) {
  102. return valueForEach;
  103. }
  104. return ForEach.meshPrimitiveTarget(primitive, function(target) {
  105. return ForEach.meshPrimitiveTargetAttribute(target, function(accessorId) {
  106. if (!defined(visited[accessorId])) {
  107. visited[accessorId] = true;
  108. var value = handler(accessorId);
  109. if (defined(value)) {
  110. return value;
  111. }
  112. }
  113. });
  114. });
  115. });
  116. });
  117. };
  118. ForEach.accessorContainingIndexData = function(gltf, handler) {
  119. var visited = {};
  120. return ForEach.mesh(gltf, function(mesh) {
  121. return ForEach.meshPrimitive(mesh, function(primitive) {
  122. var indices = primitive.indices;
  123. if (defined(indices) && !defined(visited[indices])) {
  124. visited[indices] = true;
  125. var value = handler(indices);
  126. if (defined(value)) {
  127. return value;
  128. }
  129. }
  130. });
  131. });
  132. };
  133. ForEach.animation = function(gltf, handler) {
  134. return ForEach.topLevel(gltf, 'animations', handler);
  135. };
  136. ForEach.animationChannel = function(animation, handler) {
  137. var channels = animation.channels;
  138. return ForEach.object(channels, handler);
  139. };
  140. ForEach.animationSampler = function(animation, handler) {
  141. var samplers = animation.samplers;
  142. return ForEach.object(samplers, handler);
  143. };
  144. ForEach.buffer = function(gltf, handler) {
  145. return ForEach.topLevel(gltf, 'buffers', handler);
  146. };
  147. ForEach.bufferView = function(gltf, handler) {
  148. return ForEach.topLevel(gltf, 'bufferViews', handler);
  149. };
  150. ForEach.camera = function(gltf, handler) {
  151. return ForEach.topLevel(gltf, 'cameras', handler);
  152. };
  153. ForEach.image = function(gltf, handler) {
  154. return ForEach.topLevel(gltf, 'images', handler);
  155. };
  156. ForEach.compressedImage = function(image, handler) {
  157. if (defined(image.extras)) {
  158. var compressedImages = image.extras.compressedImage3DTiles;
  159. for (var type in compressedImages) {
  160. if (Object.prototype.hasOwnProperty.call(compressedImages, type)) {
  161. var compressedImage = compressedImages[type];
  162. var value = handler(compressedImage, type);
  163. if (defined(value)) {
  164. return value;
  165. }
  166. }
  167. }
  168. }
  169. };
  170. ForEach.material = function(gltf, handler) {
  171. return ForEach.topLevel(gltf, 'materials', handler);
  172. };
  173. ForEach.materialValue = function(material, handler) {
  174. var values = material.values;
  175. if (defined(material.extensions) && defined(material.extensions.KHR_techniques_webgl)) {
  176. values = material.extensions.KHR_techniques_webgl.values;
  177. }
  178. for (var name in values) {
  179. if (Object.prototype.hasOwnProperty.call(values, name)) {
  180. var value = handler(values[name], name);
  181. if (defined(value)) {
  182. return value;
  183. }
  184. }
  185. }
  186. };
  187. ForEach.mesh = function(gltf, handler) {
  188. return ForEach.topLevel(gltf, 'meshes', handler);
  189. };
  190. ForEach.meshPrimitive = function(mesh, handler) {
  191. var primitives = mesh.primitives;
  192. if (defined(primitives)) {
  193. var primitivesLength = primitives.length;
  194. for (var i = 0; i < primitivesLength; i++) {
  195. var primitive = primitives[i];
  196. var value = handler(primitive, i);
  197. if (defined(value)) {
  198. return value;
  199. }
  200. }
  201. }
  202. };
  203. ForEach.meshPrimitiveAttribute = function(primitive, handler) {
  204. var attributes = primitive.attributes;
  205. for (var semantic in attributes) {
  206. if (Object.prototype.hasOwnProperty.call(attributes, semantic)) {
  207. var value = handler(attributes[semantic], semantic);
  208. if (defined(value)) {
  209. return value;
  210. }
  211. }
  212. }
  213. };
  214. ForEach.meshPrimitiveTarget = function(primitive, handler) {
  215. var targets = primitive.targets;
  216. if (defined(targets)) {
  217. var length = targets.length;
  218. for (var i = 0; i < length; ++i) {
  219. var value = handler(targets[i], i);
  220. if (defined(value)) {
  221. return value;
  222. }
  223. }
  224. }
  225. };
  226. ForEach.meshPrimitiveTargetAttribute = function(target, handler) {
  227. for (var semantic in target) {
  228. if (Object.prototype.hasOwnProperty.call(target, semantic)) {
  229. var accessorId = target[semantic];
  230. var value = handler(accessorId, semantic);
  231. if (defined(value)) {
  232. return value;
  233. }
  234. }
  235. }
  236. };
  237. ForEach.node = function(gltf, handler) {
  238. return ForEach.topLevel(gltf, 'nodes', handler);
  239. };
  240. ForEach.nodeInTree = function(gltf, nodeIds, handler) {
  241. var nodes = gltf.nodes;
  242. if (defined(nodes)) {
  243. var length = nodeIds.length;
  244. for (var i = 0; i < length; i++) {
  245. var nodeId = nodeIds[i];
  246. var node = nodes[nodeId];
  247. if (defined(node)) {
  248. var value = handler(node, nodeId);
  249. if (defined(value)) {
  250. return value;
  251. }
  252. var children = node.children;
  253. if (defined(children)) {
  254. value = ForEach.nodeInTree(gltf, children, handler);
  255. if (defined(value)) {
  256. return value;
  257. }
  258. }
  259. }
  260. }
  261. }
  262. };
  263. ForEach.nodeInScene = function(gltf, scene, handler) {
  264. var sceneNodeIds = scene.nodes;
  265. if (defined(sceneNodeIds)) {
  266. return ForEach.nodeInTree(gltf, sceneNodeIds, handler);
  267. }
  268. };
  269. ForEach.program = function(gltf, handler) {
  270. if (hasExtension(gltf, 'KHR_techniques_webgl')) {
  271. return ForEach.object(gltf.extensions.KHR_techniques_webgl.programs, handler);
  272. }
  273. return ForEach.topLevel(gltf, 'programs', handler);
  274. };
  275. ForEach.sampler = function(gltf, handler) {
  276. return ForEach.topLevel(gltf, 'samplers', handler);
  277. };
  278. ForEach.scene = function(gltf, handler) {
  279. return ForEach.topLevel(gltf, 'scenes', handler);
  280. };
  281. ForEach.shader = function(gltf, handler) {
  282. if (hasExtension(gltf, 'KHR_techniques_webgl')) {
  283. return ForEach.object(gltf.extensions.KHR_techniques_webgl.shaders, handler);
  284. }
  285. return ForEach.topLevel(gltf, 'shaders', handler);
  286. };
  287. ForEach.skin = function(gltf, handler) {
  288. return ForEach.topLevel(gltf, 'skins', handler);
  289. };
  290. ForEach.skinJoint = function(skin, handler) {
  291. var joints = skin.joints;
  292. if (defined(joints)) {
  293. var jointsLength = joints.length;
  294. for (var i = 0; i < jointsLength; i++) {
  295. var joint = joints[i];
  296. var value = handler(joint);
  297. if (defined(value)) {
  298. return value;
  299. }
  300. }
  301. }
  302. };
  303. ForEach.techniqueAttribute = function(technique, handler) {
  304. var attributes = technique.attributes;
  305. for (var attributeName in attributes) {
  306. if (Object.prototype.hasOwnProperty.call(attributes, attributeName)) {
  307. var value = handler(attributes[attributeName], attributeName);
  308. if (defined(value)) {
  309. return value;
  310. }
  311. }
  312. }
  313. };
  314. ForEach.techniqueUniform = function(technique, handler) {
  315. var uniforms = technique.uniforms;
  316. for (var uniformName in uniforms) {
  317. if (Object.prototype.hasOwnProperty.call(uniforms, uniformName)) {
  318. var value = handler(uniforms[uniformName], uniformName);
  319. if (defined(value)) {
  320. return value;
  321. }
  322. }
  323. }
  324. };
  325. ForEach.techniqueParameter = function(technique, handler) {
  326. var parameters = technique.parameters;
  327. for (var parameterName in parameters) {
  328. if (Object.prototype.hasOwnProperty.call(parameters, parameterName)) {
  329. var value = handler(parameters[parameterName], parameterName);
  330. if (defined(value)) {
  331. return value;
  332. }
  333. }
  334. }
  335. };
  336. ForEach.technique = function(gltf, handler) {
  337. if (hasExtension(gltf, 'KHR_techniques_webgl')) {
  338. return ForEach.object(gltf.extensions.KHR_techniques_webgl.techniques, handler);
  339. }
  340. return ForEach.topLevel(gltf, 'techniques', handler);
  341. };
  342. ForEach.texture = function(gltf, handler) {
  343. return ForEach.topLevel(gltf, 'textures', handler);
  344. };
  345. export default ForEach;