goldbergBuilder.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import { Vector3 } from "../../Maths/math.vector.js";
  2. import { Color4 } from "../../Maths/math.color.js";
  3. import { Mesh } from "../../Meshes/mesh.js";
  4. import { VertexData } from "../mesh.vertexData.js";
  5. import { Logger } from "../../Misc/logger.js";
  6. import { _PrimaryIsoTriangle, GeodesicData } from "../geodesicMesh.js";
  7. import { GoldbergMesh } from "../goldbergMesh.js";
  8. import { CompatibilityOptions } from "../../Compat/compatibilityOptions.js";
  9. /**
  10. * Creates the Mesh for a Goldberg Polyhedron
  11. * @param options an object used to set the following optional parameters for the polyhedron, required but can be empty
  12. * @param goldbergData polyhedronData defining the Goldberg polyhedron
  13. * @returns GoldbergSphere mesh
  14. */
  15. export function CreateGoldbergVertexData(options, goldbergData) {
  16. const size = options.size;
  17. const sizeX = options.sizeX || size || 1;
  18. const sizeY = options.sizeY || size || 1;
  19. const sizeZ = options.sizeZ || size || 1;
  20. const sideOrientation = options.sideOrientation === 0 ? 0 : options.sideOrientation || VertexData.DEFAULTSIDE;
  21. const positions = [];
  22. const indices = [];
  23. const normals = [];
  24. const uvs = [];
  25. let minX = Infinity;
  26. let maxX = -Infinity;
  27. let minY = Infinity;
  28. let maxY = -Infinity;
  29. for (let v = 0; v < goldbergData.vertex.length; v++) {
  30. minX = Math.min(minX, goldbergData.vertex[v][0] * sizeX);
  31. maxX = Math.max(maxX, goldbergData.vertex[v][0] * sizeX);
  32. minY = Math.min(minY, goldbergData.vertex[v][1] * sizeY);
  33. maxY = Math.max(maxY, goldbergData.vertex[v][1] * sizeY);
  34. }
  35. let index = 0;
  36. for (let f = 0; f < goldbergData.face.length; f++) {
  37. const verts = goldbergData.face[f];
  38. const a = Vector3.FromArray(goldbergData.vertex[verts[0]]);
  39. const b = Vector3.FromArray(goldbergData.vertex[verts[2]]);
  40. const c = Vector3.FromArray(goldbergData.vertex[verts[1]]);
  41. const ba = b.subtract(a);
  42. const ca = c.subtract(a);
  43. const norm = Vector3.Cross(ca, ba).normalize();
  44. for (let v = 0; v < verts.length; v++) {
  45. normals.push(norm.x, norm.y, norm.z);
  46. const pdata = goldbergData.vertex[verts[v]];
  47. positions.push(pdata[0] * sizeX, pdata[1] * sizeY, pdata[2] * sizeZ);
  48. const vCoord = (pdata[1] * sizeY - minY) / (maxY - minY);
  49. uvs.push((pdata[0] * sizeX - minX) / (maxX - minX), CompatibilityOptions.UseOpenGLOrientationForUV ? 1 - vCoord : vCoord);
  50. }
  51. for (let v = 0; v < verts.length - 2; v++) {
  52. indices.push(index, index + v + 2, index + v + 1);
  53. }
  54. index += verts.length;
  55. }
  56. VertexData._ComputeSides(sideOrientation, positions, indices, normals, uvs);
  57. const vertexData = new VertexData();
  58. vertexData.positions = positions;
  59. vertexData.indices = indices;
  60. vertexData.normals = normals;
  61. vertexData.uvs = uvs;
  62. return vertexData;
  63. }
  64. /**
  65. * Creates the Mesh for a Goldberg Polyhedron which is made from 12 pentagonal and the rest hexagonal faces
  66. * @see https://en.wikipedia.org/wiki/Goldberg_polyhedron
  67. * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/creation/polyhedra/goldberg_poly
  68. * @param name defines the name of the mesh
  69. * @param options an object used to set the following optional parameters for the polyhedron, required but can be empty
  70. * @param scene defines the hosting scene
  71. * @returns Goldberg mesh
  72. */
  73. export function CreateGoldberg(name, options, scene = null) {
  74. const size = options.size;
  75. const sizeX = options.sizeX || size || 1;
  76. const sizeY = options.sizeY || size || 1;
  77. const sizeZ = options.sizeZ || size || 1;
  78. let m = options.m || 1;
  79. if (m !== Math.floor(m)) {
  80. m === Math.floor(m);
  81. Logger.Warn("m not an integer only floor(m) used");
  82. }
  83. let n = options.n || 0;
  84. if (n !== Math.floor(n)) {
  85. n === Math.floor(n);
  86. Logger.Warn("n not an integer only floor(n) used");
  87. }
  88. if (n > m) {
  89. const temp = n;
  90. n = m;
  91. m = temp;
  92. Logger.Warn("n > m therefore m and n swapped");
  93. }
  94. const primTri = new _PrimaryIsoTriangle();
  95. primTri.build(m, n);
  96. const geodesicData = GeodesicData.BuildGeodesicData(primTri);
  97. const goldbergData = geodesicData.toGoldbergPolyhedronData();
  98. const goldberg = new GoldbergMesh(name, scene);
  99. options.sideOrientation = Mesh._GetDefaultSideOrientation(options.sideOrientation);
  100. goldberg._originalBuilderSideOrientation = options.sideOrientation;
  101. const vertexData = CreateGoldbergVertexData(options, goldbergData);
  102. vertexData.applyToMesh(goldberg, options.updatable);
  103. goldberg.goldbergData.nbSharedFaces = geodesicData.sharedNodes;
  104. goldberg.goldbergData.nbUnsharedFaces = geodesicData.poleNodes;
  105. goldberg.goldbergData.adjacentFaces = geodesicData.adjacentFaces;
  106. goldberg.goldbergData.nbFaces = goldberg.goldbergData.nbSharedFaces + goldberg.goldbergData.nbUnsharedFaces;
  107. goldberg.goldbergData.nbFacesAtPole = (goldberg.goldbergData.nbUnsharedFaces - 12) / 12;
  108. for (let f = 0; f < geodesicData.vertex.length; f++) {
  109. goldberg.goldbergData.faceCenters.push(Vector3.FromArray(geodesicData.vertex[f]));
  110. goldberg.goldbergData.faceCenters[f].x *= sizeX;
  111. goldberg.goldbergData.faceCenters[f].y *= sizeY;
  112. goldberg.goldbergData.faceCenters[f].z *= sizeZ;
  113. goldberg.goldbergData.faceColors.push(new Color4(1, 1, 1, 1));
  114. }
  115. for (let f = 0; f < goldbergData.face.length; f++) {
  116. const verts = goldbergData.face[f];
  117. const a = Vector3.FromArray(goldbergData.vertex[verts[0]]);
  118. const b = Vector3.FromArray(goldbergData.vertex[verts[2]]);
  119. const c = Vector3.FromArray(goldbergData.vertex[verts[1]]);
  120. const ba = b.subtract(a);
  121. const ca = c.subtract(a);
  122. const norm = Vector3.Cross(ca, ba).normalize();
  123. const z = Vector3.Cross(ca, norm).normalize();
  124. goldberg.goldbergData.faceXaxis.push(ca.normalize());
  125. goldberg.goldbergData.faceYaxis.push(norm);
  126. goldberg.goldbergData.faceZaxis.push(z);
  127. }
  128. return goldberg;
  129. }
  130. //# sourceMappingURL=goldbergBuilder.js.map