Making A Mesh Deformation Ocean

The wave position is actually that of the neighboring bones interpolated, Not the position it self

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.

help is appreciated, thanks

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.


done using this oneliner

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.

1 Like

You can try checking the bones WorldPosition before it is renamed, and moving it back to where it originally was after the rename.

Not sure if thatā€™ll mess up the mesh though.

1 Like

good solution but it didnā€™t work. it did the same exact thing shown in my last messages image.

1 Like

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?

nope
you can ask chatgpt to edit the py code to fit your needs. just be specific with it

i solved the issue

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
1 Like

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

pretty much what I was trying to recommend but I didnā€™t know exactly what you wanted to achieve, so I got close enough to let you carry on to success

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)
2 Likes