goldbergMesh.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. import { Vector3 } from "../Maths/math.vector.js";
  2. import { VertexBuffer } from "../Buffers/buffer.js";
  3. import { Mesh } from "../Meshes/mesh.js";
  4. import { Color4 } from "../Maths/math.color.js";
  5. import { Logger } from "../Misc/logger.js";
  6. Mesh._GoldbergMeshParser = (parsedMesh, scene) => {
  7. return GoldbergMesh.Parse(parsedMesh, scene);
  8. };
  9. /**
  10. * Mesh for a Goldberg Polyhedron which is made from 12 pentagonal and the rest hexagonal faces
  11. * @see https://en.wikipedia.org/wiki/Goldberg_polyhedron
  12. */
  13. export class GoldbergMesh extends Mesh {
  14. constructor() {
  15. super(...arguments);
  16. /**
  17. * Defines the specific Goldberg data used in this mesh construction.
  18. */
  19. this.goldbergData = {
  20. faceColors: [],
  21. faceCenters: [],
  22. faceZaxis: [],
  23. faceXaxis: [],
  24. faceYaxis: [],
  25. nbSharedFaces: 0,
  26. nbUnsharedFaces: 0,
  27. nbFaces: 0,
  28. nbFacesAtPole: 0,
  29. adjacentFaces: [],
  30. };
  31. }
  32. /**
  33. * Gets the related Goldberg face from pole infos
  34. * @param poleOrShared Defines the pole index or the shared face index if the fromPole parameter is passed in
  35. * @param fromPole Defines an optional pole index to find the related info from
  36. * @returns the goldberg face number
  37. */
  38. relatedGoldbergFace(poleOrShared, fromPole) {
  39. if (fromPole === void 0) {
  40. if (poleOrShared > this.goldbergData.nbUnsharedFaces - 1) {
  41. Logger.Warn("Maximum number of unshared faces used");
  42. poleOrShared = this.goldbergData.nbUnsharedFaces - 1;
  43. }
  44. return this.goldbergData.nbUnsharedFaces + poleOrShared;
  45. }
  46. if (poleOrShared > 11) {
  47. Logger.Warn("Last pole used");
  48. poleOrShared = 11;
  49. }
  50. if (fromPole > this.goldbergData.nbFacesAtPole - 1) {
  51. Logger.Warn("Maximum number of faces at a pole used");
  52. fromPole = this.goldbergData.nbFacesAtPole - 1;
  53. }
  54. return 12 + poleOrShared * this.goldbergData.nbFacesAtPole + fromPole;
  55. }
  56. _changeGoldbergFaceColors(colorRange) {
  57. for (let i = 0; i < colorRange.length; i++) {
  58. const min = colorRange[i][0];
  59. const max = colorRange[i][1];
  60. const col = colorRange[i][2];
  61. for (let f = min; f < max + 1; f++) {
  62. this.goldbergData.faceColors[f] = col;
  63. }
  64. }
  65. const newCols = [];
  66. for (let f = 0; f < 12; f++) {
  67. for (let i = 0; i < 5; i++) {
  68. newCols.push(this.goldbergData.faceColors[f].r, this.goldbergData.faceColors[f].g, this.goldbergData.faceColors[f].b, this.goldbergData.faceColors[f].a);
  69. }
  70. }
  71. for (let f = 12; f < this.goldbergData.faceColors.length; f++) {
  72. for (let i = 0; i < 6; i++) {
  73. newCols.push(this.goldbergData.faceColors[f].r, this.goldbergData.faceColors[f].g, this.goldbergData.faceColors[f].b, this.goldbergData.faceColors[f].a);
  74. }
  75. }
  76. return newCols;
  77. }
  78. /**
  79. * Set new goldberg face colors
  80. * @param colorRange the new color to apply to the mesh
  81. */
  82. setGoldbergFaceColors(colorRange) {
  83. const newCols = this._changeGoldbergFaceColors(colorRange);
  84. this.setVerticesData(VertexBuffer.ColorKind, newCols);
  85. }
  86. /**
  87. * Updates new goldberg face colors
  88. * @param colorRange the new color to apply to the mesh
  89. */
  90. updateGoldbergFaceColors(colorRange) {
  91. const newCols = this._changeGoldbergFaceColors(colorRange);
  92. this.updateVerticesData(VertexBuffer.ColorKind, newCols);
  93. }
  94. _changeGoldbergFaceUVs(uvRange) {
  95. const uvs = this.getVerticesData(VertexBuffer.UVKind);
  96. for (let i = 0; i < uvRange.length; i++) {
  97. const min = uvRange[i][0];
  98. const max = uvRange[i][1];
  99. const center = uvRange[i][2];
  100. const radius = uvRange[i][3];
  101. const angle = uvRange[i][4];
  102. const points5 = [];
  103. const points6 = [];
  104. let u;
  105. let v;
  106. for (let p = 0; p < 5; p++) {
  107. u = center.x + radius * Math.cos(angle + (p * Math.PI) / 2.5);
  108. v = center.y + radius * Math.sin(angle + (p * Math.PI) / 2.5);
  109. if (u < 0) {
  110. u = 0;
  111. }
  112. if (u > 1) {
  113. u = 1;
  114. }
  115. points5.push(u, v);
  116. }
  117. for (let p = 0; p < 6; p++) {
  118. u = center.x + radius * Math.cos(angle + (p * Math.PI) / 3);
  119. v = center.y + radius * Math.sin(angle + (p * Math.PI) / 3);
  120. if (u < 0) {
  121. u = 0;
  122. }
  123. if (u > 1) {
  124. u = 1;
  125. }
  126. points6.push(u, v);
  127. }
  128. for (let f = min; f < Math.min(12, max + 1); f++) {
  129. for (let p = 0; p < 5; p++) {
  130. uvs[10 * f + 2 * p] = points5[2 * p];
  131. uvs[10 * f + 2 * p + 1] = points5[2 * p + 1];
  132. }
  133. }
  134. for (let f = Math.max(12, min); f < max + 1; f++) {
  135. for (let p = 0; p < 6; p++) {
  136. //120 + 12 * (f - 12) = 12 * f - 24
  137. uvs[12 * f - 24 + 2 * p] = points6[2 * p];
  138. uvs[12 * f - 23 + 2 * p] = points6[2 * p + 1];
  139. }
  140. }
  141. }
  142. return uvs;
  143. }
  144. /**
  145. * set new goldberg face UVs
  146. * @param uvRange the new UVs to apply to the mesh
  147. */
  148. setGoldbergFaceUVs(uvRange) {
  149. const newUVs = this._changeGoldbergFaceUVs(uvRange);
  150. this.setVerticesData(VertexBuffer.UVKind, newUVs);
  151. }
  152. /**
  153. * Updates new goldberg face UVs
  154. * @param uvRange the new UVs to apply to the mesh
  155. */
  156. updateGoldbergFaceUVs(uvRange) {
  157. const newUVs = this._changeGoldbergFaceUVs(uvRange);
  158. this.updateVerticesData(VertexBuffer.UVKind, newUVs);
  159. }
  160. /**
  161. * Places a mesh on a particular face of the goldberg polygon
  162. * @param mesh Defines the mesh to position
  163. * @param face Defines the face to position onto
  164. * @param position Defines the position relative to the face we are positioning the mesh onto
  165. */
  166. placeOnGoldbergFaceAt(mesh, face, position) {
  167. const orientation = Vector3.RotationFromAxis(this.goldbergData.faceXaxis[face], this.goldbergData.faceYaxis[face], this.goldbergData.faceZaxis[face]);
  168. mesh.rotation = orientation;
  169. mesh.position = this.goldbergData.faceCenters[face]
  170. .add(this.goldbergData.faceXaxis[face].scale(position.x))
  171. .add(this.goldbergData.faceYaxis[face].scale(position.y))
  172. .add(this.goldbergData.faceZaxis[face].scale(position.z));
  173. }
  174. /**
  175. * Serialize current mesh
  176. * @param serializationObject defines the object which will receive the serialization data
  177. */
  178. serialize(serializationObject) {
  179. super.serialize(serializationObject);
  180. serializationObject.type = "GoldbergMesh";
  181. const goldbergData = {};
  182. goldbergData.adjacentFaces = this.goldbergData.adjacentFaces;
  183. goldbergData.nbSharedFaces = this.goldbergData.nbSharedFaces;
  184. goldbergData.nbUnsharedFaces = this.goldbergData.nbUnsharedFaces;
  185. goldbergData.nbFaces = this.goldbergData.nbFaces;
  186. goldbergData.nbFacesAtPole = this.goldbergData.nbFacesAtPole;
  187. if (this.goldbergData.faceColors) {
  188. goldbergData.faceColors = [];
  189. for (const color of this.goldbergData.faceColors) {
  190. goldbergData.faceColors.push(color.asArray());
  191. }
  192. }
  193. if (this.goldbergData.faceCenters) {
  194. goldbergData.faceCenters = [];
  195. for (const vector of this.goldbergData.faceCenters) {
  196. goldbergData.faceCenters.push(vector.asArray());
  197. }
  198. }
  199. if (this.goldbergData.faceZaxis) {
  200. goldbergData.faceZaxis = [];
  201. for (const vector of this.goldbergData.faceZaxis) {
  202. goldbergData.faceZaxis.push(vector.asArray());
  203. }
  204. }
  205. if (this.goldbergData.faceYaxis) {
  206. goldbergData.faceYaxis = [];
  207. for (const vector of this.goldbergData.faceYaxis) {
  208. goldbergData.faceYaxis.push(vector.asArray());
  209. }
  210. }
  211. if (this.goldbergData.faceXaxis) {
  212. goldbergData.faceXaxis = [];
  213. for (const vector of this.goldbergData.faceXaxis) {
  214. goldbergData.faceXaxis.push(vector.asArray());
  215. }
  216. }
  217. serializationObject.goldbergData = goldbergData;
  218. }
  219. /**
  220. * Parses a serialized goldberg mesh
  221. * @param parsedMesh the serialized mesh
  222. * @param scene the scene to create the goldberg mesh in
  223. * @returns the created goldberg mesh
  224. */
  225. static Parse(parsedMesh, scene) {
  226. const goldbergData = parsedMesh.goldbergData;
  227. goldbergData.faceColors = goldbergData.faceColors.map((el) => Color4.FromArray(el));
  228. goldbergData.faceCenters = goldbergData.faceCenters.map((el) => Vector3.FromArray(el));
  229. goldbergData.faceZaxis = goldbergData.faceZaxis.map((el) => Vector3.FromArray(el));
  230. goldbergData.faceXaxis = goldbergData.faceXaxis.map((el) => Vector3.FromArray(el));
  231. goldbergData.faceYaxis = goldbergData.faceYaxis.map((el) => Vector3.FromArray(el));
  232. const goldberg = new GoldbergMesh(parsedMesh.name, scene);
  233. goldberg.goldbergData = goldbergData;
  234. return goldberg;
  235. }
  236. }
  237. //# sourceMappingURL=goldbergMesh.js.map