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

getMeshPrimitives.js 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import addAllToArray from "../Core/addAllToArray.js";
  2. import defined from "../Core/defined.js";
  3. import Frozen from "../Core/Frozen.js";
  4. import WebGLConstants from "../Core/WebGLConstants.js";
  5. /**
  6. * Get an array of primitives for a given mesh. If the EXT_mesh_primitive_restart extension is present, use it to combine groups of primitives.
  7. * If the extension is not present or its spec is violated, return the original mesh.primitives.
  8. * @param {object} mesh A mesh from the glTF meshes array
  9. * @returns {object[]} An array of mesh primitives
  10. * @private
  11. */
  12. function getMeshPrimitives(mesh) {
  13. const meshExtensions = mesh.extensions ?? Frozen.EMPTY_OBJECT;
  14. const primitiveRestartExtension = meshExtensions.EXT_mesh_primitive_restart;
  15. const meshPrimitives = mesh.primitives;
  16. if (!defined(primitiveRestartExtension)) {
  17. return meshPrimitives;
  18. }
  19. // Note: per the spec, any violation of the extension's specification should cause us to fall back to mesh.primitives, if detecting the violation is feasible.
  20. // Start with a copy of mesh.primitives. For each group, replace the first primitive in the group with a primitive representing the entire group,
  21. // and set the rest of the primitives in the group to `undefined`.
  22. // This allows us to identify which remaining primitives do not use primitive restart, and any errors involving a primitive appearing in more than one group.
  23. const primitives = [];
  24. addAllToArray(primitives, meshPrimitives);
  25. for (const group of primitiveRestartExtension.primitiveGroups) {
  26. // Spec: the group must not be empty and all indices must be valid array indices into mesh.primitives.
  27. const firstPrimitiveIndex = group.primitives[0];
  28. if (!defined(firstPrimitiveIndex) || !meshPrimitives[firstPrimitiveIndex]) {
  29. return meshPrimitives;
  30. }
  31. const primitive = {
  32. ...meshPrimitives[firstPrimitiveIndex],
  33. indices: group.indices,
  34. };
  35. // Spec: primitive restart only supported for these topologies.
  36. switch (primitive.mode) {
  37. case WebGLConstants.TRIANGLE_FAN:
  38. case WebGLConstants.TRIANGLE_STRIP:
  39. case WebGLConstants.LINE_STRIP:
  40. case WebGLConstants.LINE_LOOP:
  41. break;
  42. default:
  43. return meshPrimitives;
  44. }
  45. for (const primitiveIndex of group.primitives) {
  46. const thisPrimitive = primitives[primitiveIndex];
  47. // Spec: all primitives must use indexed geometry and a given primitive may appear in at most one group.
  48. // Spec: all primitives must have same topology.
  49. if (
  50. !defined(thisPrimitive?.indices) ||
  51. thisPrimitive.mode !== primitive.mode
  52. ) {
  53. return meshPrimitives;
  54. }
  55. primitives[primitiveIndex] = undefined;
  56. }
  57. primitives[firstPrimitiveIndex] = primitive;
  58. }
  59. return primitives.filter(defined);
  60. }
  61. export default getMeshPrimitives;