At the moment, I am working on a skinned mesh sea. The mesh that I am using as a sea is rectangular, which I do not really like. Instead, I want it to be circular. My plan is to transform each bone so that the mesh becomes circular.

The issue is that I have not found an elegant way to transform each bone. I simply lack the mathematical skills to come up with a function that can transform the bones from a rectangular to a circular order.

I’d achieve it by placing each bone the same distance from the center bone, for example 200 studs away from the center. I have no experience with skinned meshes in Roblox, but I believe that’s how it should be.

I agree, but the problem is that the sketch is merely a simplified display of the idea. The mesh consists of multiple rings of bones that would respectively require different distances.

How many rings would there be? You could use a for-loop to loop through all the rings, then another one to loop through all the bones in the ring. To position each bone, simply divide the distance of the outer ring by the current ring’s number.

Something like:

for num, ring in pairs(allRings) do
for _, bone in pairs(ring) do
local distanceFromCenter = OUTER_RING_DIST / num
end
end

NOTE: The outer ring’s number is 1, while the inner ring is HIGHER, depending on the number of rings between them

Again, this is all just theory and I haven’t tried it out.

I did not fully manage to circle the square, but I came close enough. My idea was to normalize the offset of every bone by its angle math.atan2(bone.Position.Y, bone.Position.Z). I utilized a triangle function for this. Here is my final code:

-- This is essentially a triangle wave with a reach of [1, sqrt(2)] with a period of pi
local function getDistanceRatio(theta)
local t = theta
local p = math.pi
local a = math.sqrt(2) - 1
-- Inspired by https://www.calculushowto.com/triangle-wave-function/https://www.calculushowto.com/triangle-wave-function/
return a * math.abs(4 / p * (t - p / 2 * math.floor(2 * t / p + 0.5 )) * (-1)^math.floor(2 * t / p + 0.5)) + 1
end
for _, bone in pairs(self._bones) do
local bX = bone.Position.X
local bY = bone.Position.Z
local theta = math.atan2(bY, bX)
local k = getDistanceRatio(theta)
-- Reposition the bones to transform the mesh from rectangular to circular
bone.Position /= Vector3.new(k, 1, k)
--bone.Position *= (bone.Position.Magnitude / 10)^(1 + 0.001)
end