I have the following code to generate a sphere:
local RADIUS = 50
local Mesh = Instance.new("MeshPart")
Mesh.Size = Vector3.new(RADIUS, RADIUS, RADIUS)
Mesh.Anchored = true
Mesh.CanCollide = false
local EditableMesh = Instance.new("EditableMesh")
EditableMesh.Parent = Mesh
local EditableImage = Instance.new("EditableImage")
EditableImage.Parent = Mesh
local function PointOnCubeToPointOnSphere(point: Vector3)
local x2 = point.X * point.X
local y2 = point.Y * point.Y
local z2 = point.Z * point.Z
local x = point.X * math.sqrt(1 - (y2 + z2) / 2 + (y2 * z2) / 3)
local y = point.Y * math.sqrt(1 - (z2 + x2) / 2 + (z2 * x2) / 3)
local z = point.Z * math.sqrt(1 - (x2 + y2) / 2 + (x2 * y2) / 3)
return Vector3.new(x, y, z)
end
function EarthController:CreateFace(normal: Vector3, resolution: number, name: string)
local faceMesh = Mesh:Clone()
faceMesh.Parent = workspace
faceMesh.Name = name
local editableMesh: EditableMesh = faceMesh:FindFirstChild("EditableMesh")
local axisA = Vector3.new(normal.Y, normal.Z, normal.X)
local axisB = axisA:Cross(normal)
local vertices = {}
for x = 1, resolution do
vertices[x] = {}
for y = 1, resolution do
local t = Vector2.new(x, y) / (resolution + 1)
local point = normal + axisA * (2 * t.X - 1) + axisB * (2 * t.Y - 1)
local normalised = PointOnCubeToPointOnSphere(point)
local vertex = editableMesh:AddVertex(normalised)
vertices[x][y] = vertex
end
end
for x = 1, #vertices do
for y = 1, #vertices[x] do
if x == #vertices then continue end
if y == #vertices[x] then continue end
local vertex = vertices[x][y]
local vertex2 = vertices[x + 1][y]
local vertex3 = vertices[x + 1][y + 1]
local vertex4 = vertices[x][y + 1]
editableMesh:AddTriangle(vertex, vertex3, vertex2)
editableMesh:AddTriangle(vertex3, vertex, vertex4)
end
end
return faceMesh
end
function EarthController:GenerateFaces(resolution: number)
local faces = {}
for _, normalId in Enum.NormalId:GetEnumItems() do
local normal = Vector3.FromNormalId(normalId)
local mesh = self:CreateFace(normal, resolution, normalId.Name)
table.insert(faces, mesh)
end
return faces
end
function EarthController:KnitStart()
self:GenerateFaces(2^6)
end
Yet, when generated, it produces this:
I’ve tried fiddling with offsets but nothing seems to work, can anyone shed any light?
Continuing on…
I got this working through a hack (I just added a arbitrary number multiplier to axisA
)
I’ve then created a new sphere which has been divided into tiles… this however, does not work at all:
I don’t know how to fix this strange pattern but there it is, can anyone shed any light as to why?
Here is the code I’m using:
local RADIUS = 50
local EarthModel = Instance.new("Model")
EarthModel.Parent = workspace
EarthModel.Name = "Earth"
local editableImages = {}
local editableMeshes = {}
function CreateFace(resolution: number, normal: Vector3, startTile: Vector2, endTile: Vector2, parent: Instance)
local vertices = {}
local Mesh = Instance.new("MeshPart")
Mesh.Size = Vector3.one
Mesh.Anchored = true
Mesh.CanCollide = false
Mesh.Parent = parent
local EditableImage = Instance.new("EditableImage")
EditableImage.Parent = Mesh
local EditableMesh = Instance.new("EditableMesh")
EditableMesh.Parent = Mesh
local axisA = Vector3.new(normal.Y, normal.Z, normal.X)
local axisB = normal:Cross(axisA)
local tileY = startTile.Y
local differenceX = (endTile.X - startTile.X) / resolution
local differenceY = (endTile.Y - startTile.Y) / resolution
for x = 1, resolution do
local tileX = startTile.X
vertices[x] = {}
for y = 1, resolution do
local pointOnUnitCube = normal + (tileX - 0.5) * 2 * axisA + (tileY - 0.5) * 2 * axisB
local pointOnUnitSphere = pointOnUnitCube.Unit
local verticePosition = pointOnUnitSphere * RADIUS
local vertice = EditableMesh:AddVertex(verticePosition)
vertices[x][y] = vertice
tileX += differenceX
end
tileY += differenceY
end
for x = 1, #vertices do
for y = 1, #vertices[x] do
if x == #vertices then continue end
if y == #vertices[x] then continue end
local vertex = vertices[x][y]
local vertex2 = vertices[x + 1][y]
local vertex3 = vertices[x + 1][y + 1]
EditableMesh:AddTriangle(vertex, vertex3, vertex2)
end
end
end
function GenerateMeshes(resolution: number, subdivisions: number)
local meshes = {}
local faceCoveragePerSubFace = 1 / subdivisions
for _, normal in Enum.NormalId:GetEnumItems() do
local faceNormal = Vector3.FromNormalId(normal)
local faceModel = Instance.new("Model")
faceModel.Name = normal.Name
faceModel.Parent = EarthModel
for x = 1, subdivisions do
for y = 1, subdivisions do
local startTile = Vector2.new(x, y) * faceCoveragePerSubFace
local endTile = startTile + Vector2.one * faceCoveragePerSubFace
local face = self:CreateFace(resolution, faceNormal, startTile, endTile, faceModel)
table.insert(meshes, face)
end
end
end
return meshes
end
GenerateMeshes(2^6, 7)