无事|

Nolca

园龄:6年9个月粉丝:12关注:9

blender 使用物理骨骼,受物理影响+不影响主观能动性的"物理妥协骨骼" 插件:wiggle bone / rigid bone

类型上: Mesh网格 ≠ Bone骨骼

骨骼物理

代理骨骼(纯物理模拟) + 驱动器

优点:方便解耦,运算速度快
缺点:碰撞箱得再做一个代理,否则碰撞体积不准确;
应用场景:全身都得进入物理模拟
思路:RIG摆姿势骨(非控制骨)→姿态同步到phy骨架→phy原旋转加上物理模拟的后旋转→映射回RIG控制骨

前提:骨骼位置先对齐,2个骨架对应的骨骼命名一致
可调参数q=False,此时使用Eular_XYZ运算

import bpy
q=True
#act=bpy.context.selected_pose_bones_from_active_object
act=bpy.data.objects['phy.001'].pose.bones
src_obj=bpy.data.objects['C']
src=src_obj.pose.bones
mode_str='quaternion' if q else 'euler'
rot_str='QUATERNION' if q else 'XYZ'
# QUATERNION XYZ AXIS_ANGLE
axis='xyzw'
for bone in src:
bone.rotation_mode=rot_str
for abone in act:
abone.rotation_mode=rot_str
# QUATERNION XYZ AXIS_ANGLE
abone.driver_remove('rotation_'+mode_str)
# continue
len=4 if q else 3
dri = [abone.driver_add('rotation_'+mode_str, i) for i in range(len)]
i=3 if q else 0
for dr_ in dri:
dr=dr_.driver
try:
transf=dr.variables['Transform']
except:
transf = dr.variables.new()
transf.name = 'Transform'
transf.type = 'TRANSFORMS'
target = transf.targets[0]
target.id=src_obj
target.rotation_mode=rot_str.upper()
target.bone_target = abone.name
target.transform_type = 'ROT_'+axis[i].upper()
target.transform_space='WORLD_SPACE'
# WORLD_SPACE LOCAL_SPACE TRANSFORM_SPACE
dr.use_self=True
if (i!=3):
dr.expression = "(self.rotation_"+mode_str+'.'+axis[i]+"+Transform)/2"
else:
dr.expression = "Transform"
# dr.expression = "copysign(1,Transform)*max(abs(Transform),0.1)"
# It's hard to solve the sign change while crossing the axis, which cause the bone position suddenly changes
i=(i+1)%4
# https://docs.blender.org/api/3.5/bpy.types.DriverTarget.html#bpy.types.DriverTarget.transform_space

代理骨骼+约束器(约束控制骨骼)

已弃用此方法,因为wiggleBone(可能)先于约束器进行运算,导致超过3条链,Mix使用“相加”数值则会太过了,导致不正确的旋转
需要以下bpy脚本,批量添加约束,其中phy是纯粹的物理模拟用的骨骼(可以从metarig复制)

import bpy
cpName='phy'
cp_obj=bpy.data.objects[cpName]
cp_bones=bpy.data.objects[cpName].pose.bones
print(cp_bones)
selected_bones = [bone for bone in bpy.context.selected_pose_bones]
for bone in selected_bones:
# for con in bone.constraints:
print('bc',bone.constraints)
if not bone.constraints:
bone.constraints.new('COPY_ROTATION')
print('YES')
ctmp=bone.constraints["Copy Rotation"]
print('ctmp',ctmp)
ctmp.target = cp_obj
ctmp.subtarget = bone.name
ctmp.target_space="LOCAL"
ctmp.owner_space='LOCAL'
ctmp.influence=0.333
# pose.bones["b_6_0"].constraints["Copy Rotation"].influence

物理↔控制骨骼互相影响:
image

Wiggle Bone

https://github.com/shteeve3d/blender-wiggle-2

(此方法已弃用,当骨架有1000多跟骨骼时,比如rigify生成的人:human-metarig,耦合的骨骼,运算很慢)
复制需要物理模拟的控制骨,做2层一样的控制骨,在DEF的需要物理模拟的骨骼中加约束,影响:0.5
image

需要以下脚本来快速找到骨骼约束、被约束的关系:

import bpy
ob = bpy.context.selected_objects[0]
pose = ob.pose
for bonename in pose.bones.keys():
bone = pose.bones[bonename]
for const in bone.constraints:
try:
print(bone.name, '->'+const.subtarget,sep='\t')
except:
pass

解决wiggle异常抖动

世界空间局部空间
image
成功!

批量删除选中的骨骼约束

import bpy
selected_bones = [bone for bone in bpy.context.selected_pose_bones]
for bone in selected_bones:
for con in bone.constraints:
bone.constraints.remove(con)

bone dynamics + simpliCage代理网格做布料碰撞

没有wiggle bone那么卡,当然没有弹簧特性
https://www.bilibili.com/video/BV1Ye411G74K

rigid bone

https://github.com/Pauan/blender-rigid-body-bones

ps: wiggleBone仅影响旋转
要位移的用rigid bone,但碰撞不好调,容易鬼畜

网格物理+钉固顶点组(不建议)

被钉固的网格顶点,会被上一个修改器修改
布料模拟最蛋疼的地方就是,每次都得从第0帧开始播放模拟

本文作者:Nolca

本文链接:https://www.cnblogs.com/nolca/p/17473214.html

版权声明:本作品采用 收益分享revenue sharing 许可协议进行许可。

posted @   Nolca  阅读(584)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 ⏩intro 山姆精
  2. 2 🎸吉他 马叉
  3. 3 ☁升调 山姆精
  4. 4 🐦Flutter Virtual Riot/Madi
  5. 5 🎶纯律 山姆精
  6. 6 👻yeah~Color Bass! VR
🎸吉他 - 马叉
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.