| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- -- lovr-icosphere v0.0.1
- -- https://github.com/bjornbytes/lovr-icosphere
- -- MIT License
- local phi = (1 + math.sqrt(5)) / 2
- return function(subdivisions)
- local vertices = {
- { -1, phi, 0 },
- { 1, phi, 0 },
- { -1, -phi, 0 },
- { 1, -phi, 0 },
- { 0, -1, phi },
- { 0, 1, phi },
- { 0, -1, -phi },
- { 0, 1, -phi },
- { phi, 0, -1 },
- { phi, 0, 1 },
- { -phi, 0, -1 },
- { -phi, 0, 1 }
- }
- local indices = {
- 1, 12, 6,
- 1, 6, 2,
- 1, 2, 8,
- 1, 8, 11,
- 1, 11, 12,
- 2, 6, 10,
- 6, 12, 5,
- 12, 11, 3,
- 11, 8, 7,
- 8, 2, 9,
- 4, 10, 5,
- 4, 5, 3,
- 4, 3, 7,
- 4, 7, 9,
- 4, 9, 10,
- 5, 10, 6,
- 3, 5, 12,
- 7, 3, 11,
- 9, 7, 8,
- 10, 9, 2
- }
- -- Cache vertex splits to avoid duplicates
- local splits = {}
- -- Splits vertices i and j, creating a new vertex and returning the index
- local function split(i, j)
- local key = i < j and (i .. ',' .. j) or (j .. ',' .. i)
- if not splits[key] then
- local x = (vertices[i][1] + vertices[j][1]) / 2
- local y = (vertices[i][2] + vertices[j][2]) / 2
- local z = (vertices[i][3] + vertices[j][3]) / 2
- table.insert(vertices, { x, y, z })
- splits[key] = #vertices
- end
- return splits[key]
- end
- -- Subdivide
- for _ = 1, subdivisions or 0 do
- for i = #indices, 1, -3 do
- local v1, v2, v3 = indices[i - 2], indices[i - 1], indices[i - 0]
- local a = split(v1, v2)
- local b = split(v2, v3)
- local c = split(v3, v1)
- table.insert(indices, v1)
- table.insert(indices, a)
- table.insert(indices, c)
- table.insert(indices, v2)
- table.insert(indices, b)
- table.insert(indices, a)
- table.insert(indices, v3)
- table.insert(indices, c)
- table.insert(indices, b)
- table.insert(indices, a)
- table.insert(indices, b)
- table.insert(indices, c)
- table.remove(indices, i - 0)
- table.remove(indices, i - 1)
- table.remove(indices, i - 2)
- end
- end
- -- Normalize
- for i, v in ipairs(vertices) do
- local x, y, z = unpack(v)
- local length = math.sqrt(x * x + y * y + z * z)
- v[1], v[2], v[3] = x / length, y / length, z / length
- end
- return vertices, indices
- end
|