To anyone interested in transfering simulations from Blender to Godot, I made this python script for blender that creates a rig to bake the cloth/liquid simulations to a rig, based on this video.
import bpy
from bpy import context
from mathutils import Vector
def AddEmptiesAtVertices(length):
objects = bpy.context.view_layer.objects
obj = objects.active
coll = bpy.data.collections.new("empties")
bpy.context.scene.collection.children.link(coll)
if not obj or obj.type != 'MESH':
return
empties = []
for v in obj.data.vertices:
mt = bpy.data.objects.new(
f"Vert{v.index}",
None,
)
mt.empty_display_type = 'ARROWS'
mt.empty_display_size = length
mt.parent = obj
mt.parent_type = 'VERTEX'
mt.parent_vertices = [v.index] * 3
coll.objects.link(mt)
empties.append(mt)
return empties
def AddBonesAtVertices(length, use_normals, empty_names):
objects = bpy.context.view_layer.objects
obj = objects.active
if not obj or obj.type != 'MESH':
return
points = []
normals = []
data = []
for v in 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)
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
bpy.ops.object.editmode_toggle()
for i, l in enumerate(zip(points, normals)):
bone = amt.edit_bones.new(str(i))
bone.head = l[0]
bone.tail = l[1]
bpy.ops.object.posemode_toggle()
pose_bone = bpy.context.object.pose.bones[str(i)]
bpy.context.object.data.bones.active = pose_bone.bone
pose_bone.bone.select = True
constraint = pose_bone.constraints.new("COPY_LOCATION")
constraint.target = empty_names[i]
bpy.ops.object.editmode_toggle()
bpy.ops.object.editmode_toggle()
bpy.ops.object.mode_set(mode='OBJECT')
empties = AddEmptiesAtVertices(0.5)
AddBonesAtVertices(0.5, False, empties)
Once you have the simulation, you run the script having the mesh with the simulation selected. Then it will create a bunch of empties parented to each vertex of the mesh, and a rig with a bone position at each vertex of the rig and with a copy location constraint pointing to their empty counterpart. This way, the rig follows the simulation. Depending on the amount of vertices and the specs of your computer, the script can freeze Blender for a while, be patient!
To bake the simulation to the rig you can go to pose mode, select all the bones, and go to pose > animation > bake action. It will open this menu:
The important setting here is Visual Keying, where the information of the copy location constraint resides. Once baked, voilĂ , you have a rig with an animation doing the simulation that you can export to Godot. I used this method for simulating the sail in a ship:
I still haven’t tested the performance of this method. It creates a rig with as many bones as vertices in the mesh, and the animations can have one keyframe per frame (this one depends on how you bake the action in blender).
