icosphere.lua 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. -- lovr-icosphere v0.0.1
  2. -- https://github.com/bjornbytes/lovr-icosphere
  3. -- MIT License
  4. local phi = (1 + math.sqrt(5)) / 2
  5. return function(subdivisions)
  6. local vertices = {
  7. { -1, phi, 0 },
  8. { 1, phi, 0 },
  9. { -1, -phi, 0 },
  10. { 1, -phi, 0 },
  11. { 0, -1, phi },
  12. { 0, 1, phi },
  13. { 0, -1, -phi },
  14. { 0, 1, -phi },
  15. { phi, 0, -1 },
  16. { phi, 0, 1 },
  17. { -phi, 0, -1 },
  18. { -phi, 0, 1 }
  19. }
  20. local indices = {
  21. 1, 12, 6,
  22. 1, 6, 2,
  23. 1, 2, 8,
  24. 1, 8, 11,
  25. 1, 11, 12,
  26. 2, 6, 10,
  27. 6, 12, 5,
  28. 12, 11, 3,
  29. 11, 8, 7,
  30. 8, 2, 9,
  31. 4, 10, 5,
  32. 4, 5, 3,
  33. 4, 3, 7,
  34. 4, 7, 9,
  35. 4, 9, 10,
  36. 5, 10, 6,
  37. 3, 5, 12,
  38. 7, 3, 11,
  39. 9, 7, 8,
  40. 10, 9, 2
  41. }
  42. -- Cache vertex splits to avoid duplicates
  43. local splits = {}
  44. -- Splits vertices i and j, creating a new vertex and returning the index
  45. local function split(i, j)
  46. local key = i < j and (i .. ',' .. j) or (j .. ',' .. i)
  47. if not splits[key] then
  48. local x = (vertices[i][1] + vertices[j][1]) / 2
  49. local y = (vertices[i][2] + vertices[j][2]) / 2
  50. local z = (vertices[i][3] + vertices[j][3]) / 2
  51. table.insert(vertices, { x, y, z })
  52. splits[key] = #vertices
  53. end
  54. return splits[key]
  55. end
  56. -- Subdivide
  57. for _ = 1, subdivisions or 0 do
  58. for i = #indices, 1, -3 do
  59. local v1, v2, v3 = indices[i - 2], indices[i - 1], indices[i - 0]
  60. local a = split(v1, v2)
  61. local b = split(v2, v3)
  62. local c = split(v3, v1)
  63. table.insert(indices, v1)
  64. table.insert(indices, a)
  65. table.insert(indices, c)
  66. table.insert(indices, v2)
  67. table.insert(indices, b)
  68. table.insert(indices, a)
  69. table.insert(indices, v3)
  70. table.insert(indices, c)
  71. table.insert(indices, b)
  72. table.insert(indices, a)
  73. table.insert(indices, b)
  74. table.insert(indices, c)
  75. table.remove(indices, i - 0)
  76. table.remove(indices, i - 1)
  77. table.remove(indices, i - 2)
  78. end
  79. end
  80. -- Normalize
  81. for i, v in ipairs(vertices) do
  82. local x, y, z = unpack(v)
  83. local length = math.sqrt(x * x + y * y + z * z)
  84. v[1], v[2], v[3] = x / length, y / length, z / length
  85. end
  86. return vertices, indices
  87. end