Estoy diseñando un script para guardar mallas animadas en un archivo maj que es un formato que invente para después cargarlo en mis juegos, está todo listo menos esto: no sé cómo guardar las transformaciones del objeto armature.
Intente con esto:
#ob_arm : el objeto armature.
Def gettotalmatrix(bon):
Pose = ob_arm, getpose () tpos_b = pose, Bones[bon, name] tmat=pos_b, localmatrix tif(bon, hasparent()):
Return mat*gettotalmatrix(bon, parent), invert() telse:
Return mat.
Def getmatrix(bon, free):
Global ob_arm tblender. Set(curframe, free) treturn gettotalmatrix(bon).
Pero no funciona las transformaciones de los huesos no se guardan como deben, cuando los huesos no tienen padres o los padres no se mueven parecen guardarse bien, pero me di cuenta que no es así.
Lo que quiero es obtener la matriz que aplicada a un Vector este siga los movimientos del hueso.
Agradezco su ayuda.
Para obtener las matrices de los huesos de una armadura en espacio local (relativas a sus padres) en Blender, debes acceder a la matriz de pose en el espacio local del hueso padre. El código que muestras tiene errores de sintaxis y lógica.
Lo más directo y actual es usar la propiedad matrix_basis del hueso de pose. Esta matriz representa la transformación de la pose del hueso relativa a su posición de reposo en el espacio local del hueso padre. Es exactamente lo que necesitas para animación.
Aquí tienes un enfoque correcto. Asegúrate de que ob_arm es tu objeto armadura y que estás en el modo pose.
Primero, debes actualizar las matrices de la pose y de la armadura. Esto es crucial para que los cálculos sean correctos en cualquier fotograma. Usa ob_arm.update_from_editmode() y ob_arm.update_tag() seguido de bpy.context.view_layer.update().
Para cada hueso en la pose, su matriz en espacio local (relativa a su padre) se obtiene con pose_bone.matrix_basis. Si el hueso no tiene padre, esta matriz es relativa al espacio de la armadura.
Un script funcional sería así:
import bpy
ob_arm = bpy.context.object # Asegúrate de que este es tu objeto armadura
scene = bpy.context.scene
frame_actual = scene.frame_current
Itera sobre los fotogramas que quieras guardar
for frame in range(frame_inicial, frame_final + 1):
scene.frame_set(frame)
bpy.context.view_layer.update() # Actualiza las transformaciones
for pose_bone in ob_arm.pose.bones:
# Esta es la matriz de transformación local que buscas
matriz_local = pose_bone.matrix_basis.copy()
# Ahora puedes guardar 'matriz_local' en tu archivo
# Para cada fotograma y cada hueso.
Recuerda que matrix_basis es la transformación de la animación (ubicación, rotación, escala) aplicada sobre la posición de reposo del hueso en su espacio local. Es la forma estándar y correcta de exportar animaciones hueso a hueso.
Si necesitas la matriz de transformación completa que incluye la posición de reposo del hueso en el espacio del modelo, debes combinar matrix_basis con la matriz de reposo del hueso de la armadura (bone.matrix_local del hueso de datos). Pero para tu descripción, donde quieres que un vector siga al hueso, probablemente necesites la matriz en espacio mundial.
Para obtener la matriz final en espacio mundial que transforma un vértice desde el espacio del modelo hasta la posición influenciada por el hueso, debes calcular la matriz de deformación. Esta es la matriz que usan los vértices de la malla. Puedes obtenerla con pose_bone.matrix @ pose_bone.bone.matrix_local.inverted(). Luego, para un vector en coordenadas del modelo, multiplicas por esa matriz.
La clave es decidir qué espacio necesitas. Para animación esquelética pura, guardar matrix_basis por fotograma es lo habitual. Para deformar vértices directamente, necesitas la matriz de deformación en espacio mundial.