You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在世界空间而非局部空间移动动画网格的顶点?

问题:顶点向量添加始终作用于对象局部空间(骨骼变形后无效)

我尝试为选中对象的顶点添加一个向量,代码如下:

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 22:12:47