如何在世界空间而非局部空间移动动画网格的顶点?
问题:顶点向量添加始终作用于对象局部空间(骨骼变形后无效)
我尝试为选中对象的顶点添加一个向量,代码如下:
def force(self): gravity = mathutils.Vector((0.0, 0.0, -0.5)) obj = bpy.context.object obj.data.vertices[0].co += gravity
操作步骤:
- 网格处于静止姿态
- 执行
force()方法 - 网格通过骨骼修改器产生变形
- 再次执行
force()方法
可见顶点的平移仍作用于对象局部空间。我曾尝试使用对象的matrix_world,但该方案无效,因我仅修改顶点而非对象,对象变换始终为单位矩阵。恳请提供可行方案。
解决方案
因为骨骼修改器是实时计算顶点的世界空间位置,而直接修改原始顶点数据操作的是局部空间,所以变形后添加向量仍基于原始局部空间。要让向量作用于变形后的世界空间顶点,需先获取骨骼修改后的顶点世界坐标,转换回局部空间再修改原始顶点数据。
修改后的代码如下:
import bpy import mathutils def force(self): gravity = mathutils.Vector((0.0, 0.0, -0.5)) obj = bpy.context.object # 获取对象世界矩阵的逆矩阵,用于将世界坐标转回局部空间 world_inv = obj.matrix_world.inverted() # 获取包含骨骼修改器计算结果的依赖图与评估对象 depsgraph = bpy.context.evaluated_depsgraph_get() eval_obj = obj.evaluated_get(depsgraph) eval_mesh = eval_obj.to_mesh() # 计算变形后的顶点世界坐标,添加重力后转回局部空间 deformed_world_co = eval_obj.matrix_world @ eval_mesh.vertices[0].co new_world_co = deformed_world_co + gravity new_local_co = world_inv @ new_world_co # 更新原始顶点的局部坐标 obj.data.vertices[0].co = new_local_co # 清理临时生成的评估网格 eval_obj.to_mesh_clear()
关键逻辑说明
- 使用
evaluated_depsgraph_get()获取依赖图,拿到经过骨骼变形后的评估对象,这个对象的顶点坐标是已经应用了所有修改器后的结果 - 将变形后的局部顶点坐标通过
matrix_world转换为世界空间,添加重力向量后,再用逆世界矩阵转换回对象局部空间,最后赋值给原始顶点 - 每次执行该方法时,都是基于当前骨骼变形后的实际世界位置来叠加向量,而非原始的局部空间位置
内容的提问来源于stack exchange,提问作者Garfield
相关产品推荐
相关产品推荐

