for my game i need the bones specifically sorted in order (i.e. bone 0 and 1 must be right next to each other, not on opposite sides of the plane) bone 0, 1, 2, 3, 4, etc; otherwise i cant optimize it how i want
is there a pre-existing fbx file which has this (5,6,or 7 subdivides), or is there a modified version of the code which does exactly this? it’s very important that the bones are in order.
May I ask what kind of optimization you’re trying to do?
You could use the distance from the player for filtering which bones need to update (more frequently).
its not just optimization, my entire system idea revolves around the bones being assorted.
ive already tried your idea, it doesn’t work in my scenario. i need to get the nearest few bones which usually requires sorting or some degree of sorting (which im trying to avoid- i have a lot of bones), and i cant get the nearest few bones how i want and make my system as i made it if their names arent pre-assorted like i described. i have a very specific case.
the details don’t matter, ive considered many other ways of doing this and ive realized the cons of said ways. all i need at this point is a plane with assorted bone, or the code to make such plane. thanks again for your help.
I’m not sure how having the bones a different name at runtime might help with optimization?
But anyway, depending on how you want the sort, you could maybe write a command that would rename the bones how you want them to be in-studio.
When hearing ‘get closest positions’ I thought about octrees. Maybe that’s worth a try too.
octrees are very excessive for what i’m trying to do, especially since i have a solution in mind and all i need is each bones name in numerical order.
and renaming the bones programmatically causes them to move positions. i’ve already tried that yesterday.
for k, v in ipairs(workspace.WaterSkin.Plane2:GetChildren()) do if (v.ClassName=='Bone') then v.Name = k end end
genuinely all i need is each bone sorted in order so i can implement my optimized solution. bones 0, 1, 2, and 3 are corners on the plane, what i need is them in order, as well as every other bone in order.
you can use a command bar code that loops which renames bones in regions or specific positions starting from top left and moving down towards bottom right.
I have an idea of what kind of optimization you’re trying to do. I’d suggest naming the bones with a coordinate system X,Y.
get the distance between bones and use that distance (10 studs between the bones for instance)
Say there are 70 bones per row and 70 columns, do: (and this is just a very shallow example)
for x = 1,70 do
for y = 1,70 do
-- get the bone that is in the position of vector3.new(x*spacebetweenbones,0,y*spacebetweenbones) and name it x.."_"..y
end
end
ill try this but the issue is that i cannot rename bones, as it causes them to move. and no, thats not the optimization i’m trying to do. i made a system theoretically more optimized. do you have a modified version of the python code that names each bone in order, or do you have a plane with each bone named in order?
local vecOffset = Vector3.new(150, 0, 150)
local index = 1
for x = 1, 22 do
for z = 1, 22 do
for k, v in ipairs(bones) do
if ((v.Position - vecOffset).Magnitude <= 2) then
newBoneOriginalIndices[index] = k
newBones[index] = v
index += 1
end
end
vecOffset -= Vector3.new(0, 0, 14.286)
end
vecOffset = Vector3.new(vecOffset.X - 14.286, 0, 150)
end
14.286 is the spacing between each bone. 22x22 is how many bone there are on the x and z. this allows me to index bones based on only a simple addition or subtraction to the nearest bones index
twiceLanguish was extremely close, but my friend at school beat him so good game
I had the same issue, so I modified the Python script to sort the vectors from the vertices in a grid.
Here’s the modified Python script for anyone who needs their bone names to align with a grid.
import bpy
from mathutils import Vector
def sort_vectors_in_grid(vectors, num_columns):
return sorted(vectors, key=lambda vector: (vector[0][1] + 10000, vector[0][0] + 10000))
def AddBonesAtVertices(obj, length, use_normals):
if not obj or obj.type != 'MESH':
return
points = []
normals = []
indices = []
for i, v in enumerate(obj.data.vertices):
p = obj.matrix_world @ v.co
target = v.normal @ obj.matrix_world
dir = target - p
dir.normalize()
dir = dir * length
n = p + dir * (-1)
points.append(p)
if not use_normals:
n = Vector((p[0], p[1], p[2] + length))
normals.append(n)
indices.append(i)
bpy.ops.object.mode_set(mode='OBJECT')
amt = bpy.data.armatures.new(obj.name + "_vBones")
rig = bpy.data.objects.new(obj.name + '_vRig', amt)
bpy.context.collection.objects.link(rig)
objects.active = rig
zipped_data = zip(points, normals, indices)
list_data = list(zipped_data)
sorted_data = sort_vectors_in_grid(list_data, 50)
names = [] #Will keep bone names
bpy.ops.object.editmode_toggle()
for i, l in enumerate(sorted_data):
bone = amt.edit_bones.new(str(i))
bone.head = l[0]
bone.tail = l[1]
names.append((bone.name, l[2])) #Add name
bpy.ops.object.editmode_toggle()
for v_index, name in enumerate(names):
#Get the group
group = obj.vertex_groups.new(name=name[0])
#Link the vertex to it
group.add([name[1]], 1, 'REPLACE')
#Parent and add modifier
obj.parent = rig
modifier = obj.modifiers.new(rig.name, "ARMATURE")
modifier.object = rig
objects = bpy.context.view_layer.objects
obj = objects.active
AddBonesAtVertices(obj, 0.5, False)