powroupi / blender_mmd_tools

mmd_tools is a blender addon for importing Models and Motions of MikuMikuDance.
GNU General Public License v3.0
1.81k stars 277 forks source link

Can we construct instanced Rigging by library override about this type rigid body rig? #285

Closed gGradest closed 4 years ago

gGradest commented 4 years ago

Hi. Blender has a generic system of instances between files, but its Rigid Body seems to be a mystery. At least, with old-fashioned way of using Link and Proxy, we need to load RigidBodyWorld(Collection) and RigidBodyConstraint(Collection), add these in RigidBodyWorld configuration, and register "Scene" as BackgroundScene for some reason. This does not allow us to collect multiple characters from different .blend by Link and make all rigid bodies work. New Library Override allows us to edit Armature as perfect instance, but it is difficult to toggle MMD-IK or change MMD-Shapekey from the MMDtool dialog. Again, rigid body requires source's Scene. And now registering it as BackgroundScene removes the relationship between Armature and Mesh. I think the workflow of instantiating and loading a rig is great, but is anyone else completing this especially with MMDtools rigging?

powroupi commented 4 years ago

The following workflow should work. There might still some issues because proxy object does not maintain mmd_tools' full hierarchy of a MMD model.

  1. [File] -> [Link...] -> Link Collection or Objects of MMD model inside saved .blend file (uncheck [Instance Collections])
    • If you want to animate IK toggles, it's better to enable [Property Drivers] in MMD Display panel and save it before linking the model to other .blend file.
  2. Manually link physics objects to rigid body world collections, or run the following script in Blender Text Editor.
    
    import bpy

if not bpy.context.scene.rigidbody_world: bpy.ops.rigidbody.world_add()

rbw = bpy.context.scene.rigidbody_world if bpy.app.version < (2, 80, 0): if not rbw.group: rbw.group = bpy.data.groups.new('RigidBodyWorld') if not rbw.constraints: rbw.constraints = bpy.data.groups.new('RigidBodyConstraints') rb_objects = rbw.group.objects else: if not rbw.collection: rbw.collection = bpy.data.collections.new('RigidBodyWorld') if not rbw.constraints: rbw.constraints = bpy.data.collections.new('RigidBodyConstraints') rb_objects = rbw.collection.objects rbc_objects = rbw.constraints.objects

for i in bpy.data.objects: if i.mmd_type == 'RIGID_BODY': if i.name not in rb_objects.keys(): rb_objects.link(i) elif i.mmd_type == 'JOINT': if i.name not in rbc_objects.keys(): rbc_objects.link(i) elif i.mmd_type == 'ROOT': if not i.mmd_root.use_property_driver: i.mmd_root.use_property_driver = True


3. (Optionally) Select any object of a MMD model, go to `mmd_tools` [Morph Tools] panel -> [Bind] morphs (inside extra morph menu items) if there is any morphs other than vertex morph.
4. Select the root empty object of a MMD model, go to `mmd_tools` [Operator] panel, [Import] motion and then [Build] its physics.
5. (Optionally) Select the armature object, [Object]->[Relations]->[Make Proxy...] to make a proxy, then reassign the imported Bone Action to the proxy object in [Dope Sheet]->[Action Editor].

> ...to collect multiple characters from different .blend by Link and make all rigid bodies work.

Rigid bodies need to be linked to current collections of Rigid Body World settings to interact with each other. There seems be no way to interact with different scene's Rigid Body Worlds in Blender. :cry:
gGradest commented 4 years ago

Thanks powroupi!

I worked on this problem for a few days and found that this hierarchy will work. Collection_Char -Collection_RBDWorld -Collection_RBDConstraint -Empty/Arm/Mesh and Link Collection_Char and LibraryOverride it, and set these RBDs on RBDWorld setting. I realized that the reason RBD needs its Scene is that Linked RBDconstraint is referring to object that does not exist.

But your method will work better and easy. It is possible to merge characters. But I have a few questions here

  1. Is it possible to LibraryOverride Armature? If you follow this procedure and try to create LibraryOverride instead of creating a Proxy as the only change, nothing will happen. The reason I want to use LibraryOverride is because Proxy will not reflect the Armature changes (such as BoneConstraint) on Link's source file

2.Why rebuild RBD in MMDtools? If we have already built MMDtools RBD in Link's source file, it looks functional only running the script. Rebuild seems to destroy RBD settings that I have newly added on blender that are not in pmx.

3.Does behavior of RBD change before and after Link? I can't show you the specific PMX sorry, but the raw RBD made by MMDtools shakes quite loudly at times. We can adjust this by reducing scale or increasing mass of the RBD, but loading a perfectly balanced modification into Link can change some of the behavior significantly without Rebuild. I haven't fully understand Blender's RBDConstraint, so it may simply be a lack of consideration...

I'm very grateful for your wonderful support.

powroupi commented 4 years ago

You're welcome. :smile:

I worked on this problem for a few days and found that this hierarchy will work.

Yeah, but this way will only work for the models in single .blend file. By the way, there may have duplicated names in the dropdown list if you link multiple .blend files constain the same object/collection names. It's better to keep the names different in each .blend file as possible.

1.Is it possible to LibraryOverride Armature?

Yes, but it's a little complicated. It will create LibraryOverride in Blender File in some cases ([Outliner]->[Blender File]->[Objects]), also create full children. If the model is built, Bone Type Rigid Bodies are parented to the armature, they will be created as well when use LibraryOverride. Also, the Object1/Object2 of Joint settings do not reflect the change even if you LibraryOverride full hierarchy in my test. So you will need to carefully fix those settings and link necessary physics objects to rigid body world collections (use LibraryOverrided rigid body rather than library-linked one).

2.Why rebuild RBD in MMDtools?

It depends on which way you preferred, rebuild is necessary only when you modified MMD Rigid Body's [Rigid Type][Target Bone][Collision Group Mask] I think. (If you don't want the margin before the motion start, [Build] physics after posing the model at first frame.) If we have already built MMDtools RBD in Link's source file, above script need to be fixed for extra non-collision-constraint objects.

...
for i in bpy.data.objects:
    if i.mmd_type == 'RIGID_BODY':
        if i.name not in rb_objects.keys(): # object's name sensitive
            rb_objects.link(i)
    elif i.mmd_type in {'JOINT', 'NON_COLLISION_CONSTRAINT'}:
        if i.name not in rbc_objects.keys():
            rbc_objects.link(i)

or

...
for i in bpy.data.objects:
    if i.rigid_body:
        if i not in rb_objects.values():
            rb_objects.link(i)
    if i.rigid_body_constraint:
        if i not in rbc_objects.values():
            rbc_objects.link(i)

It's more difficult to fix if considering LibraryOverrided rigid bodies and constraints. :cry:

3.Does behavior of RBD change before and after Link?

If you use the same Physics settings in each .blend file, the behavior of RBD should be the same before and after Link. The Linear Lower/Upper Limits & Spring(Linear) of RBDConstraint will not reflect the object's scale in Blender, so it's not recommended to change object's scale. When importing/exporting PMX, currently mmd_tools only scale Linear Lower/Upper Limits, I'm not sure how to scale RigidBody/Joint settings correctly, that's why I recommend using scale 1 on import/export.

gGradest commented 4 years ago

Thanks for your reply.

I don't understand perfectly about blender's doubles name objects existence..but should care about collection name.

1. After all, it seems that LibraryOverride is not considered to save hierarchy and relationships in source file. We have to reconstruct all of these.

By the way, there is a hack that I discovered a few days ago.

  1. Llink collection containing MMDtools with [Instance Collections]
  2. Select that "orange instance object" and run Object> Relationships> LibraryOverride and get dropdown of all objects.
  3. No matter what you select that dropdown, all LibraryOverride will be constructed with keeping hierarchy (not constraint). Arm will allow the pose mode and the mesh will deform.
  4. If you run above powroupi script here, RBD will react but RBC will not work properly. 5.What we can see here is that in the RBC Object1 / 2 dropdown has two objects with the same name. In the RBC of each joint, reset Object1 / 2 to the correct one of the two views and the constraint will work. This process can do this easy scripts, so non-correct one may be non-exist path.
    
    import bpy

for obj in bpy.context.selected_objects: bpy.context.view_layer.objects.active = bpy.data.objects[obj.name] obj1 = bpy.data.objects[bpy.context.active_object.rigid_body_constraint.object1.name] obj2 = bpy.data.objects[bpy.context.active_object.rigid_body_constraint.object2.name] bpy.context.active_object.rigid_body_constraint.object1 = obj1 bpy.context.active_object.rigid_body_constraint.object2 = obj2


 6. It seems a bit slow running, the mesh also works by Build.

it has two problems.
1.This RBC Object1 / 2 seems to be fixed, so it will be released immediately when you save the file etc.
2. The operation of pause mode is slow overall
3. Quite unstable, will be terminated immediately

This is no longer a problem with MMDtools, but I hope that information can be shared with those who know more about blender than me.

2.Thanks! The last concern may be exactly this above.

3.This isn't related the subject of this thread, but is it correct to say that there is a restriction on the MMMDTools that it is not recommended to change the import scale?
I imported at 0.08 because I always wanted to use actual scale in my later VFX,  but it was always unhappy with the behavior of RBD.Now I've found it to be dramatic improvement at 1 scale. Why RBC is scale-dependent is a mystery...
Sorry to present that example model isn't mine and hard to search for right problem, but physics, such as [this model's](https://www.nicovideo.jp/watch/sm16945065) side hair for example, vary greatly in stability at scale. This does not seem to be due to gravity, as it does not change with the gravitational scale.

pre x0.08 postx1
https://imgur.com/DhGLkjg.gif

I'm sorry for many questions. 
powroupi commented 4 years ago

Your method possibly works fine. Just some notes:

I would say it's not guarantee to work as expected. If you export a MMD model with scale 0.08, load it in MMD, set gravity to 9.8*0.08, it's also unstable. I guess the physics engine just isn't working good on small scale. So I prefer to import model with scale 1 and change Blender's gravity to -9.8/0.08, the result is closer to MMD. :smile:

gGradest commented 4 years ago

Thanks more information about Library Override. Unless we have very complex and developing rig, it doesn't seem to have price that beats this instability. Well, I'll wait development of Library Override in the future.

If you export a MMD model with scale 0.08, load it in MMD, set gravity to 9.8*0.08, it's also unstable.

This may be the reason why MMD has a strange scale. I really felt that it is necessary to use flexible scale for such a hack reality simulation.

Your answers are very helpful to me. Thanks!